情景:
我们知道,电脑一般是由CPU,主板,内存,显卡,电源,硬盘几大零件注册。我们假设,这几大零件分为好中差三个等级。我们要用这些零件组装三台电脑,分别是服务器电脑,游戏电脑,普通办公电脑。
服务器电脑,我们要求CPU,主板,内存,电源,硬盘为‘好’,显卡为‘一般’。
游戏电脑,我们要求CPU,内存,显卡为‘好’。主板,电源,硬盘为‘一般’。
普通办公电脑,我们要求CPU,内存,硬盘,电源为‘一般’。显卡为‘差’。
UML类图
PcBuilder,你可以把他理解成为戴尔,联想等电脑生产商。它是一个建造电脑的抽象类,是为创建Pc对象的各个部件指定的抽象接口。
ServerBuilder等三个ConcreteBuilder,他们是具体的建造者。实现PcBuilder接口,构造和装配各个部件。
Pc,当然是指具体的电脑了。
PcDirector,指挥者,是构建一个使用PcBuild接口的对象。
代码实现
#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等几大硬件组成的。建造者模式就提供了一种“封装机制”来将各个对象的变化隔离开,最终,组合成复杂对象的过程是不会变的。
使用建造者模式,用户只需指定需要建造的类型就可以得到他们,具体的建造的过程和细节就不需知道了。
优点
l 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者。若需要新增一个电脑产品,只需再定义一个具体的建造者就行了。
l 将建造代码与表示代码分离。
缺点
l 要求所创建的产品一般具有较多的共同点。