Builder 构建器模式
2009-10-25 21:13
190 查看
Builder 构建模式要解决的是这样的问题:当我们要创建的对象很复杂的时候(通常是由很多其他的对象组合而成),我们要要复杂对象的创建过程和这个对象的表示(展示)分离开来,这样做的好处就是通过一步步的进行复杂对象的构建,由于在每一步的构造过程中可以引入参数,使得经过相同的步骤创建最后得到的对象的展示不一样。构建器模式和抽象工厂模式主要区别就是,构建器模式一步步创建对象,所以及时展开输出创建过程就似乎很重要。此外,“主管”(director)获得一个切片流(stream),并且将这些切片传递给构建器,每个切片用来执行创建过程的一步。
Builder 模式的典型通用结构类图如下:
参与者:
Builder: 为创建一个 Product 对象的各个部件指定抽象接口。
ConcreteBuilder: 不同的 Builder 实现. 1)实现 Builder 的接口以构造和装配该产品的各个部件。2)定义并确定它所创建的表示。3)提供一个检索产品的接口。
Director: 表示被构造的复杂对象。1)ConcreteBuilder 创建该产品的内部表示并定义它的装配过程。2)包含定义组成部件的对象,包括将这些部件装配成最终产品的接口。
协作:1)客户创建 Director 对象,并用它所想要的 Builder 对象进行配置。2)一旦产品部件被生成,导向器就会通知生成器。3)生成器处理导向器的请求,并将部件添加到该产品中。4)客户从生成器中检索产品。
注:在 Builder 中缺省方法为空。C++ 中,生成方法故意不声明为纯虚成员函数,而是把它们定义为空方法,这使客户只重定义他们所感兴趣的操作。
代码示例:
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
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
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:};
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
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:};
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
1://Product.h
2:#pragma once
3:#include
4:#include
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:};//*/
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
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:}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
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:}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
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:
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
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:}
相关文章推荐
- js原生设计模式——6复杂对象的构建—Builder建造者模式
- 设计模式之建造者模式(Builder)以及构建器
- 创建模式(Builder Pattern、构建模式、生成器,对象创建型模式)
- 一个超强的变builder模式构建多参数构造器
- 构建模式 Builder
- 浅谈 java 设计模式--构建模式(Builder pattern)
- JAVA构建器Builder模式
- 设计模式之构建Builder
- Solr4.6,用builder模式构建查询参数对象
- Builder 构建模式
- Builder设计模式构建NavigationBar
- 使用Builder模式构建可扩展的多个参数构造器
- 设计模式:构建器模式(Builder)
- JAVA Builder模式构建MAP/LIST的示例
- Builder设计模式构建万能Dialog
- (转)Builder模式的误区:将复杂对象的构建进行封装,就是Builder模式了吗?
- 设计模式之构建(Builder)模式 建造房子实例分析
- 创建模式(Builder Pattern、构建模式、生成器,对象创建型模式)
- java中使用Builder模式构建多个参数的构造器
- Builder模式的误区:将复杂对象的构建进行封装,就是Builder模式了吗?