Builder(DesignPattern)

Builder

目的

构造一个复杂的对象,并且构造与表示分开,同一个构建方式能达到不同的表示

动机

假设有一个富文本的编辑器,你需要将RTF转换为多种不同的正文格式(比如普通的ASCII文本或者能进行交互的窗口),倘若需要转换很多种文本格式,那么我们就需要快速实现新的转换方式。因此我们可以构建一个文本转换器,在读入不同的标记时进行不同的转换。

使用范围

  • 构建对象的算法与对象的组成部分无关;
  • 构造的对象要有不同表示,即可能由不同的组件组成;
  • 角色:
    • builder:创建一个product的各个组件时,提供接口;
    • concretebuilder:具体实现builder的接口并提供返回产品的接口;
    • director:蓝图,指导builder如何构造产品;
    • product:被构造的对象;

效果

  • 可以根据蓝图(director)随机修改产品的内部表示
  • director可以复用builder封装的接口去生成product;
  • 精装控制product的构造,这也是与abstract factor不同的地方,后者着重在生成一系列统一风格的product,前者可以一步一步地控制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
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
// Builder.cpp : 定义控制台应用程序的入口点。
//

#include <iostream>

using namespace std;

class Product {
public:
Product() { cout << "A product..." << endl; }
};

class Builder {
public:
Builder() = default;

virtual void BuildA(){}
virtual void BuildB(){}
virtual void BuildC(){}

virtual void buildPro(){}

virtual Product* GetProduct() { return NULL; }

};

class concreteBuilder : public Builder{
public:
concreteBuilder() { product = 0; }
virtual void buildPro() { product = new Product; }
virtual void BuildA() {
cout << "build a" << endl;
}
virtual void BuildB() {
cout << "build b" << endl;
}
virtual void BuildC() {
cout << "build c" << endl;
}

virtual Product* GetProduct() {
return product;
}
private:
Product* product;
};

class Director {
public:
Product* create(Builder& builder) {
builder.buildPro();
builder.BuildA();
builder.BuildA();
builder.BuildB();
builder.BuildC();

return builder.GetProduct();
}
Director(){}
};


int main()
{
Director director;
concreteBuilder concretebuilder;
director.create(concretebuilder);
Product* pro = concretebuilder.GetProduct();

delete pro;
return 0;
}