Java设计模式-建造者模式(Builder Pattern)

建造者模式

创建一个产品时,有时产品有不同的组成成分,在其组成成分没创建完成之前,改产品是不可使用的。使用建造者模式,通过创建所有产品内部零件,组装完成后返回给用户。

例子:
举例设计LOL角色,角色包含皮肤、技能、属性、性别

Java实现:

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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/**
* 角色
*/
class Actor{
/**
* 皮肤
*/
private String skin;
/**
* 技能
*/
private String skill;
/**
* 属性
*/
private String attribute;
/**
* 性别
*/
private String gender;

public String getSkin() {
return skin;
}

public void setSkin(String skin) {
this.skin = skin;
}

public String getSkill() {
return skill;
}

public void setSkill(String skill) {
this.skill = skill;
}

public String getAttribute() {
return attribute;
}

public void setAttribute(String attribute) {
this.attribute = attribute;
}

public String getGender() {
return gender;
}

public void setGender(String gender) {
this.gender = gender;
}

@Override
public String toString() {
return "Actor{" +
"skin='" + skin + '\'' +
", skill='" + skill + '\'' +
", attribute='" + attribute + '\'' +
", gender='" + gender + '\'' +
'}';
}
}
abstract class AbstractActorBuilder{
protected Actor actor = new Actor();

/**
* 构建皮肤
*/
public abstract void buildSkin();

/**
* 构建技能
*/
public abstract void buildSkill();

/**
* 构建属性
*/
public abstract void buildAttribute();

/**
* 构建性别
*/
public abstract void buildGender();

/**
* 创建角色
* @return
*/
public Actor resultActor(){
return actor;
}

}

/**
* 德玛西亚之力建造者
*/
class GarenActorBuilder extends AbstractActorBuilder{
@Override
public void buildSkin() {
actor.setSkin("盖伦皮肤");
}

@Override
public void buildSkill() {
actor.setSkill("盖伦技能");
}

@Override
public void buildAttribute() {
actor.setAttribute("盖伦属性");
}

@Override
public void buildGender() {
actor.setGender("男");
}
}

/**
* 德邦总管建造者
*/
class XinZhaoActorBuilder extends AbstractActorBuilder{

@Override
public void buildSkin() {
actor.setSkin("赵信皮肤");
}

@Override
public void buildSkill() {
actor.setSkill("赵信技能");
}

@Override
public void buildAttribute() {
actor.setAttribute("赵信属性");
}

@Override
public void buildGender() {
actor.setGender("男");
}
}

/**
* 寒冰射手
*/
class AsheActorBuilder extends AbstractActorBuilder{
@Override
public void buildSkin() {
actor.setSkin("艾希皮肤");
}

@Override
public void buildSkill() {
actor.setSkill("艾希技能");
}

@Override
public void buildAttribute() {
actor.setAttribute("艾希属性");
}

@Override
public void buildGender() {
actor.setGender("女");
}
}

/**
* 建造组装
*/
class BuilderDirector{
/**
* 构建角色
* @param actorBuilder
* @return
*/
public Actor constructActor(AbstractActorBuilder actorBuilder){
actorBuilder.buildSkin();
actorBuilder.buildSkill();
actorBuilder.buildAttribute();
actorBuilder.buildGender();
return actorBuilder.resultActor();
}
}

public class Main {
public static void main(String[] args) {
Actor asheActor = new BuilderDirector().constructActor(new AsheActorBuilder());
//Actor{skin='艾希皮肤', skill='艾希技能', attribute='艾希属性', gender='女'}
System.out.println(asheActor);
Actor xinZhaoActor = new BuilderDirector().constructActor(new XinZhaoActorBuilder());
//Actor{skin='赵信皮肤', skill='赵信技能', attribute='赵信属性', gender='男'}
System.out.println(xinZhaoActor);
Actor garenActor = new BuilderDirector().constructActor(new GarenActorBuilder());
//Actor{skin='盖伦皮肤', skill='盖伦技能', attribute='盖伦属性', gender='男'}
System.out.println(garenActor);

}
}

在创建角色的时候,用户直接使用建造组装者创建创建相关角色,传入相关角色的创建者即可。在实际使用中,在创建各个组件的时候,应该是有规则的,通过不同的规则建造不同的角色。在后续如果新增了相关角色,可以新建一个角色建造者即可,无需修改其他相关代码。改处缺点在于,如果角色新增了其他相关组件,则修改较大。

建造者总结

建造者核心在于一步步构建一个包含多个组件的完整对象,与工厂模式不同在于通常建造者创建的对象相对工厂模式比较复杂,通常工厂模式创建的是单一或者相对不是很复杂的对象。如果将工厂模式看出汽车零件生产厂,建造者模式可以看出汽车装配厂。

建造者优点:

  1. 用户不需要知道建造细节,将产品本身和产品创建进行解耦,使相同的创建过程可以创建不同的产品。
  2. 扩展方便,符合”开闭原则”
  3. 细化了产品创建,使创建过程清晰明了
    建造者缺点:
  4. 如果产品过多,会导致建造者过多,系统过于臃肿。
  5. 如果产品组件过于复杂而且多变,会导致产品创建过程过于复杂。

建造者使用范围:

  1. 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。
  2. 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
  3. 对象的创建过程独立于创建该对象的类。在建造者模式中通过引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中。
  4. 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。