Builder 模式

  • 动机
    • 面临一个 “复杂对象” 的创建工作,其通常由各个部分的子对象用一定的算法构成。
      • 复杂对象的 各个部分 经常面临 剧烈的变化
      • 组合在一起的 “复杂对象算法”相对稳定

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class House{
public:
House(){
this->BuildPart1();//构造函数内,调用虚函数是不会调用子类的虚函数的(静态绑定)
for(int i=0;i<4;i++){
this->BuildPart2();
}
bool flag=this->BuildPart3();
if(flag){
this->BuildPart4();
}
this->BuildPart5();
}

virtual ~House(){}
protected:
virtual void BuilPart1()=0;
virtual void BuilPart2()=0;
virtual void BuilPart3()=0;
virtual void BuilPart4()=0;
virtual void BuilPart5()=0;
}

问题

  • 构造函数内,调用虚函数是不会调用子类的虚函数的(静态绑定)

改进

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
class House{
public:
Init(){
this->BuildPart1();//构造函数内,调用虚函数是不会调用子类的虚函数的(静态绑定)
for(int i=0;i<4;i++){
this->BuildPart2();
}
bool flag=this->BuildPart3();
if(flag){
this->BuildPart4();
}
this->BuildPart5();
}

virtual ~House(){}
protected:
virtual void BuilPart1()=0;
virtual void BuilPart2()=0;
virtual void BuilPart3()=0;
virtual void BuilPart4()=0;
virtual void BuilPart5()=0;
}

class StoneHouse:House{
protected:
virtual void BuilPart1(){

}
virtual void BuilPart2(){

}
virtual void BuilPart3(){

}
virtual void BuilPart4(){

}
virtual void BuilPart5(){

}
}

int main(){
House* phouse=new StoneHouse();
phouse->init();
}

模式定义

将一个 复杂对象的 “构建” 与其 “表示” 相分离,使得 同样 的构建过程(稳定)可以创建 不同的表示(变化)

改进版本

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
class House{
public:
House(){}
//.......
virtual ~House(){}

}

class HouseBuilder{

House* GetResult(){
return pHouse;
}
protected:
House* pHouse;
virtual void BuilPart1()=0;
virtual void BuilPart2()=0;
virtual void BuilPart3()=0;
virtual void BuilPart4()=0;
virtual void BuilPart5()=0;
}
class StoneHouse:House{
protected:
virtual void BuilPart1(){

}
virtual void BuilPart2(){

}
virtual void BuilPart3(){

}
virtual void BuilPart4(){

}
virtual void BuilPart5(){

}
}

class SotoneHouseBuilder:public HouseBuilder{
protected:
virtual void BuilPart1(){

}
virtual void BuilPart2(){

}
virtual void BuilPart3(){

}
virtual void BuilPart4(){

}
virtual void BuilPart5(){

}
}
class HouseDirector{
HouseBuilder* pHouseBuilder;
public:
HouseDirector(HouseBuilder* houseBuild){
this->pHouseBuilder=houseBuild;
}
House* Construct(){
pHouseBuilder->BuildPart1();//构造函数内,调用虚函数是不会调用子类的虚函数的(静态绑定)
for(int i=0;i<4;i++){
pHouseBuilder->BuildPart2();
}
bool flag=pHouseBuilder->BuildPart3();
if(flag){
pHouseBuilder->BuildPart4();
}
pHouseBuilder->BuildPart5();
return pHouseBuilder->GetResult();
}
}
int main(){
House* phouse=new StoneHouse();
phouse->init();
}
  • 改进点
    • House 其他的行为过于复杂的情况下。将构造单独分离出来做成HouseBuilder
      • House是对象的表示
      • HouseBuider是对象的构建
      • 同样的构建过程(稳定),使得同样的构建过程(稳定)可以创建不同的表示(变化)
        • HouseDirector::Construct() 方法

UML图示

建造者模式UML图

总结要点

  • Builder 模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的部分则经常变化
  • 变化的点在哪里,封装哪里—Builder 模式主要用于应对“复杂对象的各个部分”的频繁需求变动。其缺点在于难以应对 “分步骤构建算法”的变动 需求
  • 在Builder模式中,要注意不同语言构造内调用虚函数的差别(C++ vs. C#).
    • cpp中由于要掉用子类的方法,所以 不能再构造函数中使用多态 。提供init方法