建造者模式

建造者模式


概念

设计系统时有时会需要实现相对复杂对象的构建,建造者模式就是为了解决这个问题的。建造者模式返回的是由多个部件组成的复杂产品,它专注于一个复杂对象的构建。

  • 定义: 建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 结构图如下:
    建造者模式

实例

建造者模式主要由产品类,抽象建造者,具体建造者,指挥者组成,其中指挥者可根据不同需求进行更改。

以常见的成员信息统计为例子,产品类如下:

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 产品角色
*/
public class MemberInfo {
private String name;
private int age;
private String sex;
private String phone;
private String addr;
//get set 省略....
}

抽象建造者和具体建造者分别如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 建造抽象
*/
public abstract class MemberInfoBuilder {
protected MemberInfo memberInfo = new MemberInfo();
public abstract void buildName ();
public abstract void buildAge ();
public abstract void buildSex ();
public abstract void buildPhone ();
public abstract void buildAddr ();
public MemberInfo createMemmerInfo(){
return this.memberInfo;
}
}


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 XiaoHuaMemberInoBuilder extends MemberInfoBuilder{
@Override
public void buildName() {
memberInfo.setName("小花");
}
@Override
public void buildAge() {
memberInfo.setAge(22);
}
@Override
public void buildSex() {
memberInfo.setSex("女");
}
@Override
public void buildPhone() {
memberInfo.setPhone("11111111111");
}
@Override
public void buildAddr() {
memberInfo.setAddr("美国洛杉矶");
}
}

指挥者代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 指挥者
*/
public class MemberInfoController {
public MemberInfo construct (MemberInfoBuilder builder) {
MemberInfo memberInfo;
builder.buildName();
builder.buildSex();
builder.buildAge();
builder.buildAddr();
builder.buildPhone();
memberInfo = builder.createMemmerInfo();
return memberInfo;
}
public static void main(String[] args) {
MemberInfoController memberInfoController = new MemberInfoController();
MemberInfo memberInfo = memberInfoController.construct(new XiaoHuaMemberInoBuilder());
System.out.println(memberInfo.getName());//小花
}
}

上诉代码关键部分在于抽象建造者里的 protected MemberInfo memberInfo = new MemberInfo() ,将 MemBerInfo对象的访问权限设置为 protected,以便于子类可以在被覆写的抽象方法里直接对其进行操作。

总结

指挥者类的功能可以在抽象建造者里面直接实现,这样可以减少类的数目,不过违背了“开闭原则”,以后若要进行建造顺序等更改,必须修改源代码。也可以在抽象建造者里面增加钩子方法,控制具体建造过程。

缺点
  • 使用范围受到限制,适合一系列相似的复杂产品的创建
  • 加大系统复杂度,增加理解难度与运行成本
适用场景
  • 隔离复杂对象的创建与使用
  • 对象属性互相依赖,例如控制属性生成的顺序