首页 > 代码库 > 建造者模式

建造者模式

建房子要怎么建?

  首先要有一个包工头,即指挥者。为什么要请个包工头呢,因为包工头知道建房子的流程:首先打地基、然后建墙体,然后封顶,最后是装修。

  除此之外,包工头还能根据客户的需求来盖不同类型的房子,比如普通楼房和别墅。

  当然,少不了一批帮包工头干活的人,即建造者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创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

  

  

建造者模式