抽象工厂模式定义
抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。
抽象工厂模式由来
在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,当系统所提供的工厂所需生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构中属于不同类型的具体产品时需要使用抽象工厂模式。
抽象工厂模式结构
-
AbstractProduct:抽象产品角色
抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口
-
ConcreteProduct:具体产品角色
具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
-
AbstractFactory:抽象工厂角色
抽象工厂角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口
-
ConcreteFactory:具体工厂角色
具体工厂角色负责实现创建所有实例的内部逻辑
抽象工厂模式案例
工厂模式车间工厂只负责一种生产一种车,但是车分为手动挡和自动挡,还有轿车和卡车之分。后面可能还会增加其他类型,那么用工厂模式实现会造成工厂(类)太多了,而这个时候我们应该抽取其特点,再去进行抽象,我们来看下示例
1、抽象产品角色
轿车和卡车都能停车和换挡
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 轿车
abstract class ICar {
// 停车
void parking();
// 换挡
void shiftGear();
}
// 卡车
abstract class ITruck {
// 停车
void parking();
// 换挡
void shiftGear();
}
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
// 自动挡轿车
class CarAuto implements ICar {
@override
void parking() {
print("自动挡轿车, 停车挂P档");
}
@override
void shiftGear() {
print("自动挡轿车, 换挡P N D R");
}
}
// 手动挡轿车
class CarManual implements ICar {
@override
void parking() {
print("手动挡轿车, 停车挂空档, 拉手刹");
}
@override
void shiftGear() {
print("手动挡轿车, 换挡空 1 2 3 4 5 R");
}
}
// 自动挡货车
class TruckAuto implements ITruck {
@override
void parking() {
print("自动挡货车, 停车挂P档");
}
@override
void shiftGear() {
print("自动挡货车, 换挡P N D R");
}
}
// 手动挡货车
class TruckManual implements ITruck {
@override
void parking() {
print("手动挡货车, 停车挂空档, 拉手刹");
}
@override
void shiftGear() {
print("手动挡货车, 换挡空 1 2 3 4 5 R");
}
}
3、抽象工厂角色
1
2
3
4
5
6
7
// 抽象工厂角色
abstract class ICarFactory {
// 生产轿车
ICar createCar();
// 生产货车
ITruck createTruck();
}
4、具体工厂角色
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 自动挡汽车工厂
class AutoCarFactory implements ICarFactory {
@override
ICar createCar() {
return CarAuto();
}
@override
ITruck createTruck() {
return TruckAuto();
}
}
// 手动挡汽车工厂
class ManualFactory implements ICarFactory {
@override
ICar createCar() {
return CarManual();
}
@override
ITruck createTruck() {
return TruckManual();
}
}
5、使用
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
void main(List<String> args) {
// 自动挡汽车工厂
ICarFactory autoCarFactory = AutoCarFactory();
// 手动挡汽车工厂
ICarFactory manualFactory = ManualFactory();
print("------自动挡的轿车系列------");
ICar autoCar = autoCarFactory.createCar();
autoCar.parking();
autoCar.shiftGear();
print("------自动挡的卡车系列------");
ITruck autoTruck = autoCarFactory.createTruck();
autoTruck.parking();
autoTruck.shiftGear();
print("------手动挡的轿车系列------");
ICar manualCar = manualFactory.createCar();
manualCar.parking();
manualCar.shiftGear();
print("------手动挡的卡车系列------");
ITruck manualTruck = manualFactory.createTruck();
manualTruck.parking();
manualTruck.shiftGear();
}
6、运行结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Connecting to VM Service at http://127.0.0.1:58788/AGpOlTD-Wag=/
------自动挡的轿车系列------
自动挡轿车, 停车挂P档
自动挡轿车, 换挡P N D R
------自动挡的卡车系列------
自动挡货车, 停车挂P档
自动挡货车, 换挡P N D R
------手动挡的轿车系列------
手动挡轿车, 停车挂空档, 拉手刹
手动挡轿车, 换挡空 1 2 3 4 5 R
------手动挡的卡车系列------
手动挡货车, 停车挂空档, 拉手刹
手动挡货车, 换挡空 1 2 3 4 5 R
Exited
7、完整代码
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
void main(List<String> args) {
// 自动挡汽车工厂
ICarFactory autoCarFactory = AutoCarFactory();
// 手动挡汽车工厂
ICarFactory manualFactory = ManualFactory();
print("------自动挡的轿车系列------");
ICar autoCar = autoCarFactory.createCar();
autoCar.parking();
autoCar.shiftGear();
print("------自动挡的卡车系列------");
ITruck autoTruck = autoCarFactory.createTruck();
autoTruck.parking();
autoTruck.shiftGear();
print("------手动挡的轿车系列------");
ICar manualCar = manualFactory.createCar();
manualCar.parking();
manualCar.shiftGear();
print("------手动挡的卡车系列------");
ITruck manualTruck = manualFactory.createTruck();
manualTruck.parking();
manualTruck.shiftGear();
}
// 轿车
abstract class ICar {
// 停车
void parking();
// 换挡
void shiftGear();
}
// 卡车
abstract class ITruck {
// 停车
void parking();
// 换挡
void shiftGear();
}
// 自动挡轿车
class CarAuto implements ICar {
@override
void parking() {
print("自动挡轿车, 停车挂P档");
}
@override
void shiftGear() {
print("自动挡轿车, 换挡P N D R");
}
}
// 手动挡轿车
class CarManual implements ICar {
@override
void parking() {
print("手动挡轿车, 停车挂空档, 拉手刹");
}
@override
void shiftGear() {
print("手动挡轿车, 换挡空 1 2 3 4 5 R");
}
}
// 自动挡货车
class TruckAuto implements ITruck {
@override
void parking() {
print("自动挡货车, 停车挂P档");
}
@override
void shiftGear() {
print("自动挡货车, 换挡P N D R");
}
}
// 手动挡货车
class TruckManual implements ITruck {
@override
void parking() {
print("手动挡货车, 停车挂空档, 拉手刹");
}
@override
void shiftGear() {
print("手动挡货车, 换挡空 1 2 3 4 5 R");
}
}
// 抽象工厂角色
abstract class ICarFactory {
// 生产轿车
ICar createCar();
// 生产货车
ITruck createTruck();
}
// 自动挡汽车工厂
class AutoCarFactory implements ICarFactory {
@override
ICar createCar() {
return CarAuto();
}
@override
ITruck createTruck() {
return TruckAuto();
}
}
// 手动挡汽车工厂
class ManualFactory implements ICarFactory {
@override
ICar createCar() {
return CarManual();
}
@override
ITruck createTruck() {
return TruckManual();
}
}
7、分析
我们通过抽取车的共同特性进行抽象,而且抽象工厂隔离了具体类的生成,甚至都不需要知道什么时候被创建,这种模式实现了高内聚低耦合的设计目的,符合开闭原则
抽象工厂模式两个重要概念
- 产品等级结构:产品的等级结构就是其继承结构,例如上述代码中,ICar(轿车) 是一个抽象类,其子类有 AutoCar (自动挡轿车)和 ManualCar(手动挡轿车),则 轿车抽象类就与具体自动挡或者手动挡的轿车构成一个产品等级结构。
- 产品族:产品族是同一个工厂生产,位于不同产品等级结构中的一组产品,例如上述代码中,AutoCar(自动挡轿车)和 AutoTruck(自动挡货车),都是AutoCarFactory(自动挡汽车工厂)这个工厂生成的
总结
优点
- 新增新的具体工厂和产品组很方便,无需修改已有系统,符合开闭原则
- 产品组和多个对象一起工作时,能够保证客户端始终只是用同一个产品组中的对象。
- 实现高内聚低耦合的设计目的
缺点
- 新增产品对象,难以扩展抽象工厂生产新的产品,因为抽象工厂角色中规定了所有可能被创建的产品集合。
- 开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)。