抽象工厂模式

1.定义

抽象工厂模式(Abstract Factory Pattern)隶属于设计模式中的创建型模式,用于产品族的构建。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象。可以看做是简单工厂的改进(或进一步抽象)。

2.具体实现

2.1类图

161468748894

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
133
134
135
136
137
138
139
package 设计模式;

/**
* 抽象模式
* @author wht
*/
public class AbstractFactoryPattern {
public static void main(String[] args) {
CdFactory cdFactory = new CdFactory();
ScFactory scFactory = new ScFactory();
Pizza sausage = cdFactory.getPizza("Sausage");
Pizza cheese = scFactory.getPizza("Cheese");
System.out.println(sausage);
System.out.println(cheese);
}
}

/**
* 抽象产品接口
*/
interface Pizza{
/**
* 准备材料
*/
void ready();

/**
* 烹饪pizza
*/
void cook();
}
/**
* 成都香肠披萨
*/
class CdSausagePizza implements Pizza{

@Override
public void ready() {
System.out.println("准备香肠");
System.out.println("准备面粉");
}

@Override
public void cook() {
System.out.println("开始加工香肠pizza");
}
}
/**
* 成都奶酪披萨
*/
class CdCheesePizza implements Pizza{

@Override
public void ready() {
System.out.println("准备奶酪");
System.out.println("准备面粉");
}

@Override
public void cook() {
System.out.println("开始加工奶酪pizza");
}
}
/**
* 四川香肠披萨
*/
class ScSausagePizza implements Pizza{

@Override
public void ready() {
System.out.println("准备香肠");
System.out.println("准备面粉");
}

@Override
public void cook() {
System.out.println("开始加工香肠pizza");
}
}
/**
* 四川奶酪披萨
*/
class ScCheesePizza implements Pizza{

@Override
public void ready() {
System.out.println("准备奶酪");
System.out.println("准备面粉");
}

@Override
public void cook() {
System.out.println("开始加工奶酪pizza");
}
}
/**
* 抽象工厂类
*/
interface AbsFactory{
/**
* 获得披萨
* @return
*/
Pizza getPizza(String name);
}

/**
* 具体工厂类1
*/
class CdFactory implements AbsFactory{

@Override
public Pizza getPizza(String name) {
Pizza pizza = null;
if(name.equals("Sausage")){
pizza = new CdSausagePizza();
}else if(name.equals("Cheese")){
pizza = new CdCheesePizza();
}
return pizza;
}
}
/**
* 具体工厂类2
*/
class ScFactory implements AbsFactory{

@Override
public Pizza getPizza(String name) {
Pizza pizza = null;
if(name.equals("Sausage")){
pizza = new ScSausagePizza();
}else if(name.equals("Cheese")){
pizza = new ScCheesePizza();
}
return pizza;
}
}

3.优点

  • 分离了具体的类。客户通过抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出现在客户代码中。
  • 易于交换产品系列。一个具体工厂类只在初始化时出现一次,这使得改变一个应用的具体工厂变得很容易,只需改变具体的工厂即可使用不同的产品配置。
  • 有利于产品的一致性。当一个系列的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点。

4.缺点

  • 难以支持新种类的产品。因为抽象工厂接口确定了可以被创建的产品集合,所以难以扩展抽象工厂以生产新种类的产品。

5.使用场景

  • 当需要创建的对象是一系列相互关联或相互依赖的产品族时。
  • 系统中有多个产品族,但每次只使用其中的某一族产品。
  • 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。