【设计模式】——抽象工厂Abstract Factory
时间:2022-04-22
本文章向大家介绍【设计模式】——抽象工厂Abstract Factory,主要内容包括模式意图、模式结构、适合场景、代码结构、生活中的设计模式、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
模式意图
提供对象的使用接口,隐藏对象的创建过程。
模式结构
AbstractFactory 提供创建对象的接口。
ConcreteFactory 提供真正创建对象的实现类,用于组合并创建不同的对象,实现一个产品族。
AbstractProduct 提供对象的使用接口。
ConcreteProduct 提供真正的适用对象,隐藏该对象的创建过程,是工厂创建的对象。
Client 使用者,通过抽象工厂接口,使用不同的具体工厂方法创建对象组合,从而直接使用对象,无需关注对象的创建过程。
适合场景
1 系统独立于它的产品创建、组合和表示。即无需关心内部对象时如何创建的,怎么创建的,什么含义。
2 系统需要多个产品组合中的一个配置。由于对象很多,能够组合出的组合非常多,而系统只是使用某一个组合。
3 强调的对象的组合结果,而不是他们具体的接口和实现。
代码结构
AbstractFactory.java
interface AbstractFactory {
public AbstractProductA CreateProductA();
public AbstractProductB CreateProductB();
}
ConcreteFactory.java
class ConcreteFactory1 implements AbstractFactory{
@Override
public AbstractProductA CreateProductA() {
return new ConcreteProductA1();
}
@Override
public AbstractProductB CreateProductB() {
return new ConcreteProductB1();
}
}
AbstractProduct.java
interface AbstractProductA {
public void use();
}
interface AbstractProductB {
public void use();
}
ConcreteProduct.java
class ConcreteProductA1 implements AbstractProductA{
@Override
public void use() {
// TODO Auto-generated method stub
System.out.println("use A1 product!");
}
}
class ConcreteProductB1 implements AbstractProductB{
@Override
public void use() {
// TODO Auto-generated method stub
System.out.println("use B1 product!");
}
}
使用方式
public static void main(String[] args){
AbstractProductA pa;
AbstractProductB pb;
AbstractFactory fa1 = new ConcreteFactory1();
pa = fa1.CreateProductA();
pb = fa1.CreateProductB();
pa.use();
pb.use();
AbstractFactory fa2 = new ConcreteFactory2();
pa = fa2.CreateProductA();
pb = fa2.CreateProductB();
pa.use();
pb.use();
}
全部代码
1 package com.designer;
2 interface AbstractFactory {
3 public AbstractProductA CreateProductA();
4 public AbstractProductB CreateProductB();
5 }
6 interface AbstractProductA {
7 public void use();
8 }
9 interface AbstractProductB {
10 public void use();
11 }
12 class ConcreteFactory1 implements AbstractFactory{
13
14 @Override
15 public AbstractProductA CreateProductA() {
16 return new ConcreteProductA1();
17 }
18
19 @Override
20 public AbstractProductB CreateProductB() {
21 return new ConcreteProductB1();
22 }
23
24 }
25 class ConcreteFactory2 implements AbstractFactory{
26
27 @Override
28 public AbstractProductA CreateProductA() {
29 return new ConcreteProductA2();
30 }
31
32 @Override
33 public AbstractProductB CreateProductB() {
34 return new ConcreteProductB2();
35 }
36
37 }
38 class ConcreteProductA1 implements AbstractProductA{
39
40 @Override
41 public void use() {
42 // TODO Auto-generated method stub
43 System.out.println("use A1 product!");
44 }
45
46 }
47 class ConcreteProductA2 implements AbstractProductA{
48
49 @Override
50 public void use() {
51 // TODO Auto-generated method stub
52 System.out.println("use A2 product!");
53 }
54
55 }
56 class ConcreteProductB1 implements AbstractProductB{
57
58 @Override
59 public void use() {
60 // TODO Auto-generated method stub
61 System.out.println("use B1 product!");
62 }
63
64 }
65 class ConcreteProductB2 implements AbstractProductB{
66
67 @Override
68 public void use() {
69 // TODO Auto-generated method stub
70 System.out.println("use B2 product!");
71 }
72
73 }
74 public class Client {
75 public static void main(String[] args){
76 AbstractProductA pa;
77 AbstractProductB pb;
78
79 AbstractFactory fa1 = new ConcreteFactory1();
80 pa = fa1.CreateProductA();
81 pb = fa1.CreateProductB();
82 pa.use();
83 pb.use();
84
85 AbstractFactory fa2 = new ConcreteFactory2();
86 pa = fa2.CreateProductA();
87 pb = fa2.CreateProductB();
88 pa.use();
89 pb.use();
90
91 }
92 }
生活中的设计模式
在生活中,我们经常会碰到使用一系列东西的时候。比如,我们愿意吃炸鸡配啤酒,喜欢吃爆米花配可乐。我们不关心炸鸡怎么炸的,啤酒怎么酿的,爆米花怎么爆的,而只关心我们吃什么,喝什么,这就是典型的抽象工厂。
例如,大部分程序猿们都有吃早餐的习惯,当然很多人喜欢睡懒觉也来不及吃,但是为了身体健康,还是要按时吃饭才行!扯远了...
有人喜欢吃中式的,有人喜欢吃西式的。那么去食堂我们不会去问,包子怎么做的,面包怎么烤的,仅仅是付费吃饭而已。而中式一般是豆浆油条,西式面包牛奶。这种搭配已经形成了一种习惯,也就是默认的产品组合。
因此,我们在买单时,只要指定早餐的样式,就可以了。下面就是我们吃早餐,使用早餐工厂的流程...
interface BreakfastFactory{
public StapleFood MakeStapleFood();
public Drinks MakeDrinks();
}
interface StapleFood{
public void eating();
}
interface Drinks{
public void drinking();
}
class BreakfastCStyle implements BreakfastFactory{
@Override
public StapleFood MakeStapleFood() {
return new DeepFriedDoughSticks();
}
@Override
public Drinks MakeDrinks() {
return new SoybeanMilk();
}
}
class BreakfastWStyle implements BreakfastFactory {
@Override
public StapleFood MakeStapleFood() {
return new Bread();
}
@Override
public Drinks MakeDrinks() {
return new Milk();
}
}
class DeepFriedDoughSticks implements StapleFood{
@Override
public void eating() {
System.out.println("我在吃油条!...");
}
}
class SoybeanMilk implements Drinks{
@Override
public void drinking() {
System.out.println("我在喝豆浆!...");
}
}
class Bread implements StapleFood{
@Override
public void eating() {
System.out.println("我在吃面包!...");
}
}
class Milk implements Drinks{
@Override
public void drinking() {
System.out.println("我在喝牛奶!...");
}
}
public class Breakfast{
public static void main(String[] args){
StapleFood sf;
Drinks dk;
System.out.println("——————————————————第一天——————————————————————————");
System.out.println("我要吃中式早餐");
BreakfastFactory bf1 = new BreakfastCStyle();
sf = bf1.MakeStapleFood();
dk = bf1.MakeDrinks();
sf.eating();
dk.drinking();
System.out.println("——————————————————第二天——————————————————————————");
System.out.println("我要吃西式早餐");
BreakfastFactory bf2 = new BreakfastWStyle();
sf = bf2.MakeStapleFood();
dk = bf2.MakeDrinks();
sf.eating();
dk.drinking();
}
}
可以看到,非常方便的就迟到了中式和西式的早餐,而省掉了大量炸油条,烤面包的时间。
——————————————————第一天——————————————————————————
我要吃中式早餐
我在吃油条!...
我在喝豆浆!...
——————————————————第二天——————————————————————————
我要吃西式早餐
我在吃面包!...
我在喝牛奶!...
这就是一个简单的抽象工厂的使用。
- 发现插件生成的robots.txt不能被谷歌和360识别
- Github 年度开源报告:TensorFlow 成最受欢迎深度学习项目
- [持续更新]批处理重命名系列案例
- java学习之协调同步的线程
- 如何确保NFS服务安全
- ASM 翻译系列第三十八弹:ASM数据清理
- 借助PageSpeed,为Nginx网站服务器提速
- DX-watermark插件无法预览及上传图片报imagesx()错误的解决办法
- 抓取占用CPU高的JAVA线程,进而找出有问题的WEB页面
- ASM 翻译系列第三十九弹:物理元数据AT表
- ASM 翻译系列第四十弹:理解ASM中 REQUIRED_MIRROR_FREE_MB和USABLE_FILE_MB的含义
- 给XFN链接关系加上“nofollow”选项
- LVS中采用Jboss作为RealServer的配置要点
- 基于Prometheus的数据库监控
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 利用Python实现证件照底色替换(k-means)
- Linux中断处理
- Salesforce LWC学习(二十一) Error浅谈
- 活久见!64 张图带你 Maven 实战通关
- TensorFlow_Tutorial_v3b——improving NN performance测验
- Redis字典设计详解
- C++中STL学习笔记——容器之vector
- Linux定时器实现
- 如何使用Go来实现优雅重启服务?
- C++中STL学习笔记——容器之list
- C++中STL学习笔记——常见算法操作演示
- 虚拟文件系统
- Convolution_model_Step_by_Step_v2a
- 进程间通信 - 共享内存
- Redis数据淘汰算法