引:在开发应用的时候为了适应不同的操作系统以及不同数据库时,我们总会显得力不从心。而抽象工厂模式为了我们提供了优秀的解决方案。
定义
为创建一组相关或相互依赖的对象提供一个接口,而且无须指定他们的具体类。——创造类
它的通用类图如下:
为了展示通用的源代码,将原来的通用类图扩展为如下类图:
下面是基于类图的代码: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// 抽象产品类 ProductA与ProductB类似;1,2代表产品等级
public abstract class AbstractProductA {
// 每个产品共有方法
public void shareMethod() { ... }
// 每个产品相同方法,不同实现
public abstract void doSomething();
}
// 产品A1的实现类
public class ProductA1 extends AbstractProductA {
public void doSomething() {
System.out.println("产品A1的实现方法");
}
}
// 产品A2的实现类
public class ProductA2 extends AbstractProductA {
public void doSomething() {
System.out.println("产品A2的实现方法");
}
}
// 抽象工厂类 有N个产品族,在抽象工厂类就有N个创建方法
public abstract class AbstractCreator {
// 创建A产品家族
public abstract AbstractProductA createProductA();
// 创建B产品家族
public abstract AbstractProductB createProductB();
}
// 有M个产品等级就应该有M个实现工厂类,在每个实现工厂中,实现不同产品族的生产任务
// 产品等级1的实现类
public class Creator1 extends AbstractCreator {
// 只生产产品等级为1的A产品
public AbstractProductA createProductA() {
retrurn new ProductA1();
}
// 只生产产品等级为1的B产品
public AbstractProductB createProductB() {
retrurn new ProductB1();
}
}
// 产品等级2的实现类
public class Creator2 extends AbstractCreator {
// 只生产产品等级为2的A产品
public AbstractProductA createProductA() {
retrurn new ProductA2();
}
// 只生产产品等级为2的B产品
public AbstractProductB createProductB() {
retrurn new ProductB2();
}
}
// 场景类
public class Client {
public static void main(String[] args) {
// 定义两个工厂
AbstractCreator creator1 = new Creator1();
AbstractCreator creator2 = new Creator2();
// 产生A1对象
AbstractProductA a1 = creator1.createProductA();
// 产生A2对象
AbstractProductA a2 = creator2.createProductA();
// 产生B1对象
AbstractProductB b1 = creator1.createProductB();
// 产生B2对象
AbstractProductB b2 = creator2.createProductB();
}
}
主要是要理解产品族以及产品等级的关系。
应用
优点
- 封装性,它只需要了解接口。
- 产品族的约束为非公开状态。
缺点
扩展非常困难。如果要新增一个产品,需要修改AbstractCreator类以及它的实现类。这严重违反了开闭原则。
使用场景
如果一个对象族都有相同的约束,就可以使用抽象工厂模式。例如linux和windows下得编辑器和不同数据库的规范操作。
注意事项
上面的扩展困难是指产品族扩展困难,但是产品等级扩展还是容易的。
最佳实践
在涉及不同操作系统,不同数据库的时候非常适合抽象工厂模式,因为它可以屏蔽掉操作系统或数据库对应用的影响。
参考
- 《设计模式之禅》