创建型模式:抽象工厂

个人博客原文:
创建型模式:抽象工厂

景

五大创建型模式之三:抽象工厂。

简介

姓名 :抽象工厂

英文名 :Abstract Factory Pattern

价值观 :不管你有多少产品,给我就是了

个人介绍

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
(为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。)
(来自《设计模式之禅》)

今天讲的是抽象工厂模式,小伙伴可能有疑问,抽象工厂和工厂方法之间都有工厂,那肯定是有什么联系的,具体是什么关系呢?简单的说:工厂方法是在解决一个产品多个层级方面的事情;而抽象工厂致力于解决多个产品多个层级方面的事情。举个例子:汽车是由很多零件组成的,比如引擎、轮胎、方向盘等等。现在如果我们是轮胎生产方,要生产宝马轮胎和奔驰轮胎,要用工厂方法还是抽象工厂实现呢?答案是:工厂方法。轮胎是一个产品,宝马轮胎和奔驰轮胎是 2 个不同层级的轮胎,所以用工厂方法解决就足够。假如现在我们是汽车生产方,要生产宝马汽车和奔驰汽车,汽车又包含轮胎和方向盘等等,要用哪个来实现?既然是上面的是工厂方法,那这个就用抽象工厂,因为这涉及到多个产品(轮胎、方向盘等等)和 2 个层级(宝马和奔驰)。这里还没有讲抽象工厂的概念就说了工厂方法和抽象方法的区别,是不是有点陌生?嗯,先记住这个概念,分清楚两者的区别。在不同场景使用不同的设计模式。

上面定义中:为创建一组相关或相互依赖的对象提供一个接口。这样子理解这句话,比如上面说的轮胎和方向盘,宝马汽车用的轮胎和方向盘需要都是宝马品牌的,也就是说在安装宝马汽车的轮胎和方向盘的时候,得用宝马生产的轮胎和方向盘,重要的一点是:轮胎和方向盘是互相依赖的,不能在宝马汽车上安装奔驰轮胎和宝马方向盘,因为有这个依赖关系,所以我们需要提供一个额外的接口,来保证宝马汽车使用的轮胎和方向盘都是宝马生产的。这就是抽象工厂干的事情。

你要的故事

上面用汽车安装轮胎和方向盘的例子,那这里为了让大家能深入理解,就不用其他例子了。在一个设计模式讲解的过程中,我觉得用一个案例来讲解可以减少读者的阅读理解成本,为了写设计模式这一系列文章,看了不少设计模式方面的书籍,有些书籍在讲解一个设计模式的时候,用了不止一个例子,读完之后印象不是很深刻。这个系列写完之后,想要的效果是:不需要记住设计模式的定义,把这些故事以及故事对应是讲哪个设计模式都记住了,就真正掌握了这些内容了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
public class AbstractFactoryTest {

public static void main(String[] args) {
// 宝马员工安装轮胎和方向盘
AbstractCarFactory bmwCarFacatory = new BMWCarFactory();
bmwCarFacatory.installWheel();
bmwCarFacatory.installSteeringWheel();

// 奔驰员工安装轮胎和方向盘
AbstractCarFactory mercedesCarFacatory = new MercedesCarFacatory();
mercedesCarFacatory.installWheel();
mercedesCarFacatory.installSteeringWheel();
}

}

/**
* 汽车抽象工厂
*/
interface AbstractCarFactory {

void installWheel();

void installSteeringWheel();

}

/**
* 宝马工厂
*/
class BMWCarFactory implements AbstractCarFactory {

@Override
public void installWheel() {
WheelFacatory wheelFacatory = new BMWWheelFacatory();
String wheel = wheelFacatory.createWheel();
System.out.println("安装轮胎:" + wheel);
}

@Override
public void installSteeringWheel() {
SteeringWheelFacatory steeringWheelFacatory = new BMWSteeringWheelFacatory();
String steeringWheel = steeringWheelFacatory.createSteeringWheel();
System.out.println("安装方向盘:" + steeringWheel);
}
}

/**
* 奔驰工厂
*/
class MercedesCarFacatory implements AbstractCarFactory {

@Override
public void installWheel() {
WheelFacatory wheelFacatory = new MercedesWheelFacatory();
String wheel = wheelFacatory.createWheel();
System.out.println("安装轮胎:" + wheel);
}

@Override
public void installSteeringWheel() {
SteeringWheelFacatory steeringWheelFacatory = new MercedesSteeringWheelFacatory();
String steeringWheel = steeringWheelFacatory.createSteeringWheel();
System.out.println("安装方向盘:" + steeringWheel);
}
}

/**
* 轮胎工厂
*/
interface WheelFacatory {

String createWheel();

}

/**
* 宝马轮胎工厂
*/
class BMWWheelFacatory implements WheelFacatory {

@Override
public String createWheel() {
System.out.println("宝马轮胎工厂生产轮胎");
return "宝马轮胎";
}
}

/**
* 奔驰轮胎工厂
*/
class MercedesWheelFacatory implements WheelFacatory {

@Override
public String createWheel() {
System.out.println("奔驰轮胎工厂生产轮胎");
return "奔驰轮胎";
}
}

/**
* 方向盘工厂
*/
interface SteeringWheelFacatory {

String createSteeringWheel();

}

/**
* 宝马方向盘工厂
*/
class BMWSteeringWheelFacatory implements SteeringWheelFacatory {

@Override
public String createSteeringWheel() {
System.out.println("宝马方向盘工厂生产方向盘");
return "宝马方向盘";
}
}

/**
* 奔驰方向盘工厂
*/
class MercedesSteeringWheelFacatory implements SteeringWheelFacatory {

@Override
public String createSteeringWheel() {
System.out.println("奔驰方向盘工厂生产方向盘");
return "奔驰方向盘";
}
}

代码:

AbstractFactoryTest.java

还是和以往一样,思维开拓一下,这里列举的是给汽车安装轮胎和方向盘,汽车不止这些,如果要加个安装引擎呢?要怎么实现?这里我就不写出来了,让小伙伴尝试一下,写出来了就理解抽象模式这个设计模式啦。

总结

简单工厂、工厂方法、抽象工厂这几个工厂相关的设计模式的基本内容都讲完了,这几个模式都是为了解耦,为了可扩展。这里要着重说一下,三者之间没有好坏之分,只有在具体的场景才能发挥它们各自的优势。在单产品多层级,层级数量不多的情况下,可以使用简单工厂,层级多且需要支持扩展,可以使用工厂方法;在多产品多层级,可以使用抽象工厂。

参考资料:《大话设计模式》、《Java设计模式》、《设计模式之禅》、《研磨设计模式》、《Head First 设计模式》

推荐阅读:

创建型模式:单例模式
创建型模式:工厂方法

希望文章对您有所帮助,设计模式系列会持续更新,感兴趣的同学可以关注公众号,第一时间获取文章推送阅读,也可以一起交流,交个朋友。

公众号之设计模式系列文章



公众号