剖析
创建型的设计模式。关注对象创建的过程
与工厂模式的区别。
- 工厂模式关注的是生产的结果,而Builder关注的是对象的创建过程。
- 工厂并不关心对象的内部创建过程,或者说对象的创建过程已经定死了,就像工厂的流水生产线一样,你只需要给我这个对象就好了,比如:买一部iphone6,那工厂生产一部就好了。 而Builder则关心对象创建的细节,比如:组装一台电脑,所有的配置都可以自由的选择,每个不同的选择,最后出来的产品都不太一样。除了关注配件还要关注组装流程,比如有的需要先装散热器再安装主板到主机,有的需要先安装主板到主机再安装散热器。有的需要装一个内存条,有的需要装几个内存条。这些对结果都是有影响的。而且不过部件确实或者安装流程不对,可能最终这个对象就不能使用。
工厂和Builder应该怎么取选择?
当一个对象创建的过程比较简单,比如:手机,在发布时候型号功能颜色都已经确定,这是我们只需要一个手机工厂给我们创建即可。当一个对象产品比较复杂,自定义属性的比较多,同时创建的流程也比较复杂,比如组装电脑。每个配件都可以自己选择,而且组装的过程也很重要,这时候用Builder就比较合适
元素
- 抽象产品、具体产品
- 抽象构造者、具体构造者
关注创建对象中每一步的具体操作。 - 抽象指挥者、具体指挥者
关注创建对象的流程。
示例
问题
一个人需要在一块地上盖一栋别墅。
- 用工厂模式来说,他可以找土工工程的公司(Factory),公司作为工厂给他盖这栋房子,这个产品。
- 用Builder模式来说,盖房子的时候还要关注材料的选择,大小等等需要用户确定。这时候公司会派一个建筑设计师(Director),让他和用户(Client)沟通。然后设计师下面有一个团队(Builder),来具体盖房子,比如瓦匠、搬砖(部件)的等等,而具体盖房子的流程则有设计师来主导。因此在这中间用户并不和建筑团队沟通,他并不需要知道建造的细节,只需要和Director沟通好房子的属性就好。同理,当又有另个一人需要盖一个平房,那公司就派一个精通平房的设计师来过,同时带一个专业盖平方的团队即可。这个开发流程符合设计模式的基本原则。
抽象产品
class Hourse {
protected:
int size;
int height;
int level;
string name;
public:
Hourse(int size, int height, int level, string name) {
this->size = size;
this->height = height;
this->level = level;
this->name = name;
}
virtual void show()const = 0;
};
具体产品
class CottageHourse :public Hourse {
private :
double price;
public:
CottageHourse(int size, int height, int level, string name, double price) :Hourse(size, height, level, name) {
this->price = price;
}
void show() const {
cout << name.c_str() << " 规格" << endl;
cout << "大小:" << size << endl;
cout << "高度:" << height << endl;
cout << "级别:" << level << endl;
cout << "售价:" << price<<"万" << endl;
}
};
抽象构造者
class HourseBuild {
public:
virtual int makeFoundation(int size)=0;
virtual int makeWall(int height)=0;
virtual int makeDecorate(int level)=0;
};
具体构造者
class CottageHourseBuild :public HourseBuild {
int makeFoundation(int size) {
return size;
}
int makeWall(int height) {
return height;
}
int makeDecorate(int level) {
return level;
}
};
抽象指挥者
class Director {
protected:
HourseBuild* hourseBuild;
public:
Director(HourseBuild* build) {
this->hourseBuild = build;
}
virtual Hourse* createHourse() = 0;
HourseBuild* getBuild() {
return hourseBuild;
}
};
具体指挥者
class CottageDirector :public Director {
public:
CottageDirector(HourseBuild* build) :Director(build){
}
Hourse* createHourse() {
int sizeRes = getBuild()->makeFoundation(100);
int heightRes = Director::hourseBuild->makeWall(10);
int levelRes = Director::hourseBuild->makeDecorate(5);
return new CottageHourse(sizeRes, heightRes, levelRes, "海景别墅", 998);
}
};
测试调用
int main()
{
HourseBuild * build = new CottageHourseBuild();
Director *director = new CottageDirector(build);
Hourse *hourse = director->createHourse();
hourse->show();
delete hourse;
delete director;
delete build;
return 0;
}
结果
build_res.png
网友评论