首页 > 代码库 > 建造者模式
建造者模式
建房子要怎么建?
首先要有一个包工头,即指挥者。为什么要请个包工头呢,因为包工头知道建房子的流程:首先打地基、然后建墙体,然后封顶,最后是装修。
除此之外,包工头还能根据客户的需求来盖不同类型的房子,比如普通楼房和别墅。
当然,少不了一批帮包工头干活的人,即建造者Builder。
用代码描述:
1 #include <string> 2 #include <iostream> 3 #include <vector> 4 using namespace std; 5 6 // 建筑队,打地基、筑墙、盖顶、装修都会 7 class Builder 8 { 9 public:10 virtual void DaDiJi ()=0;11 virtual void ZhuQiang ()=0;12 virtual void GaiDing ()=0;13 virtual void ZhuangXiu ()=0;14 };15 // 建楼房16 Class LouFangBuilder : public Builder17 {18 public:19 virtual void DaDiJi ()20 {21 cout<<"楼房打地基"<<endl;22 }23 virtual void ZhuQiang ()24 {25 cout<<"楼房筑墙"<<endl;26 }27 virtual void GaiDing ()28 {29 cout<<"楼房盖顶"<<endl;30 }31 virtual void ZhuangXiu ()32 {33 cout<<"楼房装修"<<endl;34 }35 };36 // 建别墅37 Class BieShuBuilder : public Builder38 {39 public:40 virtual void DaDiJi ()41 {42 cout<<"别墅打地基"<<endl;43 }44 virtual void ZhuQiang ()45 {46 cout<<"别墅筑墙"<<endl;47 }48 virtual void GaiDing ()49 {50 cout<<"别墅盖顶"<<endl;51 }52 virtual void ZhuangXiu ()53 {54 cout<<"别墅装修"<<endl;55 }56 };57 58 // 包工头59 class Direct60 {61 private:62 // 包工头私有一个建筑队,只有包工头可以指挥。63 // 这个建筑队名称根据需求来定, 64 // 建楼房的时候叫楼房建筑队,建别墅的时候叫别墅建筑队65 Builder* builder;66 public:67 // 包工头指挥建筑队建房:打地基、筑墙、盖顶、装修。68 void Construct(Builder * builder)69 {70 builder->DaDiJi();71 builder->ZhuQiang();72 builder->GaiDing();73 builder->ZhuangXiu();74 }75 };76 77 // 客户端78 int main()79 {80 // 指定包工头81 Direct *director = new Direct();82 // 建楼房还是别墅83 Builder *b1 = new LouFangBuilder();84 Builder *b2 = new BieShuBuilder();85 // 包工头指挥楼房建筑队建造楼房86 director->Construct(b1);87 return 0;88 }
后来,房主说房子建好后我要检查,地基、墙体、房顶、装饰都要看看。包工头说好吧,那我就把地基、墙体、房顶、装饰作为四个装配部件,每完成一个过程,”产品“就装配一个部件,并提供展示的功能。交付产品的时候我就可以把所有部件给你看。
1 #include <string> 2 #include <vector> 3 #include <iostream> 4 using namespace std; 5 6 // 说干就干,房子作为我们的产品 7 class Product 8 { 9 vector<string> parts; 10 public: 11 // 每完成一个部件,”产品“就添加一个部件 12 void Add(const string part) 13 { 14 parts.push_back(part); 15 } 16 // 展示产品的每一个部分 17 void Show()const 18 { 19 for(int i = 0 ; i < parts.size() ; i++) 20 { 21 cout<<parts[i]<<endl; 22 } 23 } 24 }; 25 26 // 建筑队,打地基、筑墙、盖顶、装修都会 27 class Builder 28 { 29 public: 30 virtual void DaDiJi ()=0; 31 virtual void ZhuQiang ()=0; 32 virtual void GaiDing ()=0; 33 virtual void ZhuangXiu ()=0; 34 virtual Product GetResult() = 0; 35 }; 36 // 建楼房 37 class LouFangBuilder : public Builder 38 { 39 private: 40 Product product; 41 public: 42 virtual void DaDiJi() 43 { 44 product.Add("楼房地基"); // 产品添加楼房地基部件 45 } 46 virtual void ZhuQiang() 47 { 48 product.Add("楼房墙体"); // 产品添加楼房墙体部件 49 } 50 virtual void GaiDing() 51 { 52 product.Add("楼房房顶"); // 产品添加楼房房顶部件 53 } 54 virtual void ZhuangXiu() 55 { 56 product.Add("楼房装饰"); // 产品添加楼房装饰部件 57 } 58 virtual Product GetResult() 59 { 60 return product; 61 } 62 }; 63 // 建别墅 64 class BieShuBuilder : public Builder 65 { 66 private: 67 Product product; 68 public: 69 virtual void DaDiJi() 70 { 71 product.Add("别墅地基"); // 产品添加别墅地基部件 72 } 73 virtual void ZhuQiang() 74 { 75 product.Add("别墅墙体"); // 产品添加别墅墙体部件 76 } 77 virtual void GaiDing() 78 { 79 product.Add("别墅房顶"); // 产品添加别墅房顶部件 80 } 81 virtual void ZhuangXiu() 82 { 83 product.Add("别墅装饰"); // 产品添加别墅装饰部件 84 } 85 virtual Product GetResult() 86 { 87 return product; 88 } 89 }; 90 91 // 包工头 92 class Direct 93 { 94 private: 95 // 包工头私有一个建筑队,只有包工头可以指挥。 96 // 这个建筑队名称根据需求来定, 97 // 建楼房的时候叫楼房建筑队,建别墅的时候叫别墅建筑队 98 Builder* builder; 99 public:100 // 包工头指挥建筑队建房:打地基、筑墙、盖顶、装修。101 void Construct(Builder * builder)102 {103 builder->DaDiJi();104 builder->ZhuQiang();105 builder->GaiDing();106 builder->ZhuangXiu();107 }108 };109 110 int main()111 {112 // 指定包工头113 Direct *director = new Direct();114 // 建楼房还是别墅115 Builder *b1 = new LouFangBuilder();116 Builder *b2 = new BieShuBuilder();117 // 包工头指挥楼房建筑队建造楼房118 director->Construct(b1);119 120 // 楼房建好了,包工头说,这就是我们的产品121 Product p1 = b1->GetResult();122 // 产品交付,包工头把地基、墙体、房顶、装饰每一个部分都展示给房主看。123 p1.Show(); 124 return 0;125 }
可以看到,不管加不加产品类,建房子的流程是不变的,即整个Direct类没做任何改变。这就引出了建造者模式的定义:将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示。就如同样的Construct可以创建楼房也可以创建别墅。
建造者模式和工厂方法模式类似,我们将上面的第一个例子改造成工厂方法模式,看看他们的区别。
色 部分为工厂方法模式
色 部分为建造者模式。
1 #include <string> 2 #include <iostream> 3 #include <vector> 4 using namespace std; 5 // 建筑队 6 class CBuilder 7 { 8 public: 9 virtual void DaDiJi ()=0; 10 virtual void ZhuQiang ()=0; 11 virtual void GaiDing ()=0; 12 virtual void ZhuangXiu ()=0; 13 }; 14 // 建楼房 15 class LouFangBuilder : public CBuilder 16 { 17 public: 18 virtual void DaDiJi () 19 { 20 cout<<"楼房打地基"<<endl; 21 } 22 virtual void ZhuQiang () 23 { 24 cout<<"楼房筑墙"<<endl; 25 } 26 virtual void GaiDing () 27 { 28 cout<<"楼房盖顶"<<endl; 29 } 30 virtual void ZhuangXiu () 31 { 32 cout<<"楼房装修"<<endl; 33 } 34 }; 35 // 建别墅 36 class BieShuBuilder : public CBuilder 37 { 38 public: 39 virtual void DaDiJi () 40 { 41 cout<<"别墅打地基"<<endl; 42 } 43 virtual void ZhuQiang () 44 { 45 cout<<"别墅筑墙"<<endl; 46 } 47 virtual void GaiDing () 48 { 49 cout<<"别墅盖顶"<<endl; 50 } 51 virtual void ZhuangXiu () 52 { 53 cout<<"别墅装修"<<endl; 54 } 55 }; 56 57 //工厂模式 58 class CFactory 59 { 60 public: 61 virtual CBuilder* Construct() = 0; 62 }; 63 64 class LouFangFactory: public CFactory 65 { 66 CBuilder* Construct () 67 { 68 return new LouFangBuilder(); 69 } 70 }; 71 class BieShuFactory: public CFactory 72 { 73 CBuilder* Construct () 74 { 75 return new BieShuBuilder(); 76 } 77 }; 78 79 // 建造者模式 80 class Direct 81 { 82 private: 83 CBuilder* builder; 84 public: 85 void Construct(CBuilder* temp) 86 { 87 builder->DaDiJi(); 88 builder->ZhuQiang(); 89 builder->GaiDing(); 90 builder->ZhuangXiu(); 91 } 92 }; 93 94 int main() 95 { 96 // 工厂模式 97 CFactory* p = new LouFangFactory; 98 CBuilder* opr = p->Construct(); 99 opr->DaDiJi();100 opr->ZhuQiang();101 opr->GaiDing();102 opr->ZhuangXiu();103 104 // 建造者模式105 Direct *director = new Direct();106 CBuilder *b1 = new LouFangBuilder();107 CBuilder *b2 = new BieShuBuilder();108 director->Construct(b1);109 110 return 0;111 }
也就是说,工厂方法模式能生成不同的产品,也能将具体产品再分解成一个个零件,但调用的时候只能一个零件一个零件的造。
而建造者模式把造零件的过程放到了一起,当生产一个产品时,是作为整个产品生产出来,不需要一个零件一个零件的装配。
不知道为什么总感觉建造者模式一点都不像创建型模式?
最后,贴一下建造者模式的角色:
1)builder:为创建一个产品对象的各个部件指定抽象接口。
2)ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并 提供一个检索产品的接口。
3)Director:构造一个使用Builder接口的对象。
4)Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
建造者模式