谈谈设计模式——建造者模式

情景

我们知道,电脑一般是由CPU,主板,内存,显卡,电源,硬盘几大零件注册。我们假设,这几大零件分为好中差三个等级。我们要用这些零件组装三台电脑,分别是服务器电脑,游戏电脑,普通办公电脑。

  • 服务器电脑,我们要求CPU,主板,内存,电源,硬盘为‘好’,显卡为‘一般’。
  • 游戏电脑,我们要求CPU,内存,显卡为‘好’。主板,电源,硬盘为‘一般’。
  • 普通办公电脑,我们要求CPU,内存,硬盘,电源为‘一般’。显卡为‘差’。

UML类图



  • PcBuilder,你可以把他理解成为戴尔,联想等电脑生产商。它是一个建造电脑的抽象类,是为创建Pc对象的各个部件指定的抽象接口。
  • ServerBuilder等三个ConcreteBuilder,他们是具体的建造者。实现PcBuilder接口,构造和装配各个部件。
  • Pc,当然是指具体的电脑了。
  • PcDirector,指挥者,是构建一个使用PcBuild接口的对象。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <iostream>
#include<string>
using namespace std;
typedef enum HardwareLEVELenum
{
DefaultLevel,
Bad,
Normal,
Good
}HardwareLEVEL;
class PC
{
public:
void SetPC(string level){_level=level;}
void SetCPU(HardwareLEVEL CPU){ _CPU = CPU; }
void SetGPU(HardwareLEVEL GPU){ _GPU = GPU; }
void SetMotherboard(HardwareLEVEL Motherboard){ _Motherboard = Motherboard; }
void SetHarddisk(HardwareLEVEL Harddisk){ _Harddisk = Harddisk; }
void SetRAM(HardwareLEVEL RAM){ _RAM = RAM; }
void SetPower(HardwareLEVEL Power){ _Power = Power; }
void ShowPC()
{
cout<<"I'm a "<<_level<<endl;
cout<<"HardWare Level(1~3)"<<endl;
cout<<"CPU:"<<_CPU<<endl;
cout<<"GPU:"<<_GPU<<endl;
cout<<"Motherboard:"<<_Motherboard<<endl;
cout<<"Harddisk:"<<_Harddisk<<endl;
cout<<"RAM:"<<_RAM<<endl;
cout<<"Power:"<<_Power<<endl;
cout<<endl;
}
private:
string _level;
HardwareLEVEL _CPU;
HardwareLEVEL _GPU;
HardwareLEVEL _Motherboard;
HardwareLEVEL _Harddisk;
HardwareLEVEL _RAM;
HardwareLEVEL _Power;
};
class Builder
{
public:
virtual void BuildPC(){}
virtual void BuildCPU(){}
virtual void BuildGPU(){}
virtual void BuildMotherboard(){}
virtual void BuildHarddisk(){}
virtual void BuildRAM(){}
virtual void BuildPower(){}
virtual PC *GetPC(){ return NULL; }
};
class ServerPCBuilder : public Builder
{
public:
ServerPCBuilder(){ _ServerPC = new PC(); }
void BuildPC(){_ServerPC->SetPC("ServerPC");};
void BuildCPU(){ _ServerPC->SetCPU(Good); }
void BuildGPU(){ _ServerPC->SetGPU(Normal); }
void BuildMotherboard(){ _ServerPC->SetMotherboard(Good); }
void BuildHarddisk(){ _ServerPC->SetHarddisk(Good); }
void BuildRAM(){ _ServerPC->SetRAM(Good); }
void BuildPower(){ _ServerPC->SetPower(Good); }
PC *GetPC(){ return _ServerPC; }
private:
PC *_ServerPC;
};
class GamePCBuilder : public Builder
{
public:
GamePCBuilder(){ _GamerPC = new PC(); }
void BuildPC(){_GamerPC->SetPC("GamePC");};
void BuildCPU(){ _GamerPC->SetCPU(Good); }
void BuildGPU(){ _GamerPC->SetGPU(Good); }
void BuildMotherboard(){ _GamerPC->SetMotherboard(Normal); }
void BuildHarddisk(){ _GamerPC->SetHarddisk(Normal); }
void BuildRAM(){ _GamerPC->SetRAM(Good); }
void BuildPower(){ _GamerPC->SetPower(Normal); }
PC *GetPC(){ return _GamerPC; }
private:
PC *_GamerPC;
};
class OfficePCBuilder : public Builder
{
public:
OfficePCBuilder(){ _OfficePC = new PC(); }
void BuildPC(){_OfficePC->SetPC("OfficePC");};
void BuildCPU(){ _OfficePC->SetCPU(Normal); }
void BuildGPU(){ _OfficePC->SetGPU(Bad); }
void BuildMotherboard(){ _OfficePC->SetMotherboard(Normal); }
void BuildHarddisk(){ _OfficePC->SetHarddisk(Normal); }
void BuildRAM(){ _OfficePC->SetRAM(Normal); }
void BuildPower(){ _OfficePC->SetPower(Normal); }
PC *GetPC(){ return _OfficePC; }
private:
PC *_OfficePC;
};
class Director
{
public:
Director(Builder *builder) { m_Builder = builder; }
void CreatePC();
private:
Builder *m_Builder;
};
void Director::CreatePC()
{
m_Builder->BuildPC();
m_Builder->BuildCPU();
m_Builder->BuildGPU();
m_Builder->BuildMotherboard();
m_Builder->BuildHarddisk();
m_Builder->BuildMotherboard();
m_Builder->BuildHarddisk();
m_Builder->BuildRAM();
m_Builder->BuildPower();
}
int main(int argc, char *argv[])
{
Builder *builderPC1 = new ServerPCBuilder();
Director directorPC1(builderPC1);
directorPC1.CreatePC();
PC *PC1 = builderPC1->GetPC();
Builder *builderPC2 = new GamePCBuilder();
Director directorPC2(builderPC2);
directorPC2.CreatePC();
PC *PC2 = builderPC2->GetPC();
Builder *builderPC3 = new OfficePCBuilder();
Director directorPC3(builderPC3);
directorPC3.CreatePC();
PC *PC3 = builderPC3->GetPC();
if (PC1 == NULL)
return 0;
if (PC2 == NULL)
return 0;
if (PC3 == NULL)
return 0;
PC1->ShowPC();
PC2->ShowPC();
PC3->ShowPC();
delete PC1;
PC1 = NULL;
delete builderPC1;
builderPC1 = NULL;
delete PC2;
PC2 = NULL;
delete builderPC2;
builderPC2 = NULL;
delete PC3;
PC1 = NULL;
delete builderPC3;
builderPC3 = NULL;
return 0;
};

建造者模式

建造者模式(Builder),将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

就上面那个例子,我们知道,一个复杂对象(电脑)的创建,通常是由许多子对象(硬件)所组成的。由于需求的不同,组成复杂对象(电脑)的子对象(硬件)也不同(例如上面例子的服务器电脑,游戏电脑,办公电脑)。但是,我们知道,无论需求怎么样变化,电脑还是由CPU等几大硬件组成的。建造者模式就提供了一种“封装机制”来将各个对象的变化隔离开,最终,组合成复杂对象的过程是不会变的。

使用建造者模式,用户只需指定需要建造的类型就可以得到他们,具体的建造的过程和细节就不需知道了。

优点

  • 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者。若需要新增一个电脑产品,只需再定义一个具体的建造者就行了。
  • 将建造代码与表示代码分离。

缺点

  • 要求所创建的产品一般具有较多的共同点。
文章目录
  1. 1. 情景
  2. 2. UML类图
  3. 3. 代码实现
  4. 4. 建造者模式
  5. 5. 优点
  6. 6. 缺点
|