Builder 构建模式要解决的是这样的问题:当我们要创建的对象很复杂的时候(通常是由很多其他的对象组合而成),我们要要复杂对象的创建过程和这个对象的表示(展示)分离开来,这样做的好处就是通过一步步的进行复杂对象的构建,由于在每一步的构造过程中可以引入参数,使得经过相同的步骤创建最后得到的对象的展示不一样。构建器模式和抽象工厂模式主要区别就是,构建器模式一步步创建对象,所以及时展开输出创建过程就似乎很重要。此外,“主管”(director)获得一个切片流(stream),并且将这些切片传递给构建器,每个切片用来执行创建过程的一步。
Builder 模式的典型通用结构类图如下:
参与者:
Builder: 为创建一个 Product 对象的各个部件指定抽象接口。
ConcreteBuilder: 不同的 Builder 实现. 1)实现 Builder 的接口以构造和装配该产品的各个部件。2)定义并确定它所创建的表示。3)提供一个检索产品的接口。
Director: 表示被构造的复杂对象。1)ConcreteBuilder 创建该产品的内部表示并定义它的装配过程。2)包含定义组成部件的对象,包括将这些部件装配成最终产品的接口。
协作:1)客户创建 Director 对象,并用它所想要的 Builder 对象进行配置。2)一旦产品部件被生成,导向器就会通知生成器。3)生成器处理导向器的请求,并将部件添加到该产品中。4)客户从生成器中检索产品。
注:在 Builder 中缺省方法为空。C++ 中,生成方法故意不声明为纯虚成员函数,而是把它们定义为空方法,这使客户只重定义他们所感兴趣的操作。
代码示例:
1: //Builder.h
2: #pragma once
3: #include <string>
4:
5: class Product;
6:
7: //构建器基类
8: //成员函数故意不声明为纯虚函数,而是把它们定义为空方法
9: //这样可以使子类只重定义感兴趣的操作.
10: class Builder
11: {
12: public:
13: virtual ~Builder();
14: virtual void BuildPartA(const std::string& buildPara){};
15: virtual void BuildPartB(const std::string& buildPara){};
16: virtual void BuildPartC(const std::string& buildPara){};
17: Product* GetProduct();
18: protected:
19: Builder();
20: };
21: //具体的构建器1:ConcreteBuilder1
22: class ConcreteBuilder1: public Builder
23: {
24: public:
25: ~ConcreteBuilder1();
26: void BuildPartA(const std::string& buildPara);
27: void BuildPartB(const std::string& buildPara);
28: void BuildPartC(const std::string& buildPara);
29:
30: ConcreteBuilder1();
31: Product* GetProduct();
32: private:
33: Product* _product1;
34: };
35: //具体的构建器2:ConcreteBuilder2
36: class ConcreteBuilder2: public Builder
37: {
38: public:
39: ~ConcreteBuilder2();
40: void BuildPartA(const std::string& buildPara);
41: void BuildPartB(const std::string& buildPara);
42:
43: ConcreteBuilder2();
44: Product* GetProduct();
45: private:
46: Product* _product2;
47: };
1: //Director.h
2: #pragma once
3:
4: class Builder;
5:
6: class Director
7: {
8: public:
9: Director(Builder* b = 0);
10: ~Director();
11: void Construct();
12: bool setBuilder(Builder* b);
13:
14: private:
15: Builder* _bld;
16: };
1: //Product.h
2: #pragma once
3: #include
4: #include <string>
5: #include
6:
7: class ProductPart
8: {
9: public:
10: ProductPart(const std::string& part);
11: ~ProductPart();
12: std::string* getPart() const;
13: private:
14: std::string* _part;
15: };//*/
16:
17: class Product
18: {
19: private:
20: std::vector
parts;
21: typedef std::vector
partsVect;
22:
23: public:
24: Product();
25: ~Product();
26: void ProducePart(const std::string& str);
27: void displayPart();
28: };//*/
1: //Builder.cpp
2: #include "Builder.h"
3: #include "Product.h"
4: #include
5:
6: //
7: Builder::Builder(){ }
8: Builder::~Builder()
9: {
10: //std::cout << "~Builder..." << std::endl;
11:
12: }
13: Product* Builder::GetProduct()
14: {
15: return 0;
16: }
17: //ConcreteBuilder1
18: ConcreteBuilder1::ConcreteBuilder1()
19: {
20: //std::cout << "ConcreteBuilder1..." << std::endl;
21: _product1 = new Product;
22: }
23: ConcreteBuilder1::~ConcreteBuilder1()
24: {
25: //std::cout << "~ConcreteBuilder1..." << std::endl;
26: }
27: //
28: void ConcreteBuilder1::BuildPartA(const std::string& buildPara)
29: {
30: _product1->ProducePart(buildPara);
31: }
32: void ConcreteBuilder1::BuildPartB(const std::string& buildPara)
33: {
34: _product1->ProducePart(buildPara);
35: }
36: void ConcreteBuilder1::BuildPartC(const std::string& buildPara)
37: {
38: _product1->ProducePart(buildPara);
39: }
40:
41: Product* ConcreteBuilder1::GetProduct()
42: {
43: return _product1;
44: }
45:
46: //ConcreteBuilder2
47: ConcreteBuilder2::ConcreteBuilder2()
48: {
49: //std::cout << "ConcreteBuilder2..." << std::endl;
50: _product2 = new Product;
51: }
52: ConcreteBuilder2::~ConcreteBuilder2()
53: {
54: //std::cout << "~ConcreteBuilder2..." << std::endl;
55: }
56: //
57: void ConcreteBuilder2::BuildPartA(const std::string& buildPara)
58: {
59: _product2->ProducePart(buildPara);
60: }
61: void ConcreteBuilder2::BuildPartB(const std::string& buildPara)
62: {
63: _product2->ProducePart(buildPara);
64: }
65: Product* ConcreteBuilder2::GetProduct()
66: {
67: return _product2;
68: }
1: //Builder.cpp
2: #include "Builder.h"
3: #include "Product.h"
4: #include
5:
6: //
7: Builder::Builder(){ }
8: Builder::~Builder()
9: {
10: //std::cout << "~Builder..." << std::endl;
11:
12: }
13: Product* Builder::GetProduct()
14: {
15: return 0;
16: }
17: //ConcreteBuilder1
18: ConcreteBuilder1::ConcreteBuilder1()
19: {
20: //std::cout << "ConcreteBuilder1..." << std::endl;
21: _product1 = new Product;
22: }
23: ConcreteBuilder1::~ConcreteBuilder1()
24: {
25: //std::cout << "~ConcreteBuilder1..." << std::endl;
26: }
27: //
28: void ConcreteBuilder1::BuildPartA(const std::string& buildPara)
29: {
30: _product1->ProducePart(buildPara);
31: }
32: void ConcreteBuilder1::BuildPartB(const std::string& buildPara)
33: {
34: _product1->ProducePart(buildPara);
35: }
36: void ConcreteBuilder1::BuildPartC(const std::string& buildPara)
37: {
38: _product1->ProducePart(buildPara);
39: }
40:
41: Product* ConcreteBuilder1::GetProduct()
42: {
43: return _product1;
44: }
45:
46: //ConcreteBuilder2
47: ConcreteBuilder2::ConcreteBuilder2()
48: {
49: //std::cout << "ConcreteBuilder2..." << std::endl;
50: _product2 = new Product;
51: }
52: ConcreteBuilder2::~ConcreteBuilder2()
53: {
54: //std::cout << "~ConcreteBuilder2..." << std::endl;
55: }
56: //
57: void ConcreteBuilder2::BuildPartA(const std::string& buildPara)
58: {
59: _product2->ProducePart(buildPara);
60: }
61: void ConcreteBuilder2::BuildPartB(const std::string& buildPara)
62: {
63: _product2->ProducePart(buildPara);
64: }
65: Product* ConcreteBuilder2::GetProduct()
66: {
67: return _product2;
68: }
1: //Product.cpp
2: #include "Product.h"
3: #include
4:
5: //
6: ProductPart::ProductPart(const std::string& part)
7: :_part(new std::string(part))
8: { }
9:
10: ProductPart::~ProductPart()
11: {
12: if(_part)
13: {
14: delete _part;
15: _part = 0;
16: }
17: else
18: _part = 0;
19: }
20: std::string* ProductPart::getPart() const
21: {
22: return _part;
23: }
24: //
25: Product::Product(){}
26: Product::~Product()
27: {
28: //std::cout << "~Product" << std::endl;
29: partsVect::iterator iter;
30: for(iter = parts.begin(); iter != parts.end(); ++iter)
31: {
32: delete *iter;
33: *iter = 0;
34: }
35: }
36: void Product::ProducePart(const std::string& str)
37: {
38: parts.push_back(new ProductPart(str));
39: }
40: void Product::displayPart()
41: {
42: std::cout << "displayPart..." << std::endl;
43: partsVect::iterator iter;
44: for(iter = parts.begin(); iter != parts.end(); ++iter)
45: {
46: std::cout << *((*iter)->getPart()) << std::endl;
47: }
48: }
49:
1: //test.cpp
2: #include "Builder.h"
3: #include "Product.h"
4: #include "Director.h"
5: #include
6:
7: int main(int argc,char* argv[])
8: {
9: Product* p1;
10: ConcreteBuilder1* b1 = new ConcreteBuilder1;
11: Director* d1 = new Director(b1);
12: d1->Construct();
13: p1 = b1->GetProduct();
14: p1->displayPart();
15:
16: ConcreteBuilder2* b2 = new ConcreteBuilder2;
17: Product* p2;
18: if(d1->setBuilder(b2))
19: {
20: d1->Construct();
21: p2 = b2->GetProduct();
22: p2->displayPart();
23: }
24: else{
25: std::cout << "Can not create b2!" << std::endl;
26: }
27:
28: delete d1;
29: d1 = 0;
30: delete p1;
31: p1 = 0;
32: if(p2)
33: {
34: delete p2;
35: p2 = 0;
36: }
37:
38: return 0;
39: }