前言

  建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
  工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性。
  建造者模式通常包括下面几个角色:
  1、Builder:给出一个抽象接口,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建。
  2、ConcreteBuilder:实现Builder接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建。 在建造过程完成后,提供产品的实例。
  3、Director:调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。
  4、Product:要创建的复杂对象。
  主要作用:在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。
  1. 用户只需要给出指定复杂对象的类型和内容
  2. 建造者模式负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)


模式讲解:
  1. 指挥者(Director)直接和客户(Client)进行需求沟通
  2. 沟通后指挥者将客户创建产品的需求划分为各个部件的建造请求(Builder)
  3. 将各个部件的建造请求委派到具体的建造者(ConcreteBuilder)
  4. 各个具体建造者负责进行产品部件的构建
  5. 最终构建成具体产品(Product)

栗子

  这里以游戏开发中人物的构造过程为例。在游戏中创建一个形象时,需要对每个部位进行创建。简化而言,需要创建头部,身体和四肢。

1、Product

要创建的复杂对象

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
public class Person {  
private String head;
private String body;
private String foot;

public String getHead() {
return head;
}

public void setHead(String head) {
this.head = head;
}

public String getBody() {
return body;
}

public void setBody(String body) {
this.body = body;
}

public String getFoot() {
return foot;
}

public void setFoot(String foot) {
this.foot = foot;
}
}

2、Builder

给出一个抽象接口,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建

1
2
3
4
5
6
public interface PersonBuilder {  
void buildHead();
void buildBody();
void buildFoot();
Person buildPerson();//组装
}

3、ConcreteBuilder

实现Builder接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建。 在建造过程完成后,提供产品的实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ManBuilder implements PersonBuilder {  
Person person;

public ManBuilder() {
person = new Person();//创建一个person实例,用于调用set方法
}

public void buildBody() {
person.setBody("建造身体部分");
}

public void buildFoot() {
person.setFoot("建造四肢部分");
}

public void buildHead() {
person.setHead("建造头部部分");
}

public Person buildPerson() {
return person;//返回一个person实例
}
}

4、Director

调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建

1
2
3
4
5
6
7
8
9
public class PersonDirector {  
public Person constructPerson(PersonBuilder pb) {
//按照 身体--->头部--->四肢 的顺序创建人物
pb.buildHead();
pb.buildBody();
pb.buildFoot();
return pb.buildPerson();
}
}

5、测试

1
2
3
4
5
6
7
8
9
public class Test {  
public static void main(String[] args) {
PersonDirector pd = new PersonDirector();
Person person = pd.constructPerson(new ManBuilder());
System.out.println(person.getBody());
System.out.println(person.getFoot());
System.out.println(person.getHead());
}
}

输出结果:

1
2
3
建造身体部分
建造四肢部分
建造头部部分

优缺点

  • 优点:
    • 易于解耦:将产品本身与产品创建过程进行解耦,可以使用相同的创建过程来得到不同的产品。也就说细节依赖抽象。
    • 易于精确控制对象的创建:将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰
    • 易于拓展:增加新的具体建造者无需修改原有类库的代码,易于拓展,符合“开闭原则”
  • 缺点:
    • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制
    • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大

总结

  在《Effective Java》书中第二条,就提到“遇到多个构造器参数时要考虑用构建器”,其实这里的构建器就属于建造者模式,只是里面把四个角色都放到具体产品里面了。而建造者模式主要解决在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

ps:因作者能力有限,有错误的地方请见谅

  • 喜欢这篇文章的话可以用快捷键 Ctrl + D 来收藏本页

最后更新: 2018年11月21日 10:30

原始链接: https://blog.hdqyf.club/2018/11/21/20181121-建造者模式详解/

× 请我吃糖~
打赏二维码