建造者模式

ⅰ亾dé卋堺 提交于 2019-11-26 20:15:29

建房子要怎么建?

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

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

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

  

  

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!