“对象创建”模式
- 通过“对象创建” 模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。
- 典型模式
- Factory Method
- Abstract Factory
- Prototype
- Builder
这个模式用的比较少。比较像模板方法模式。
动机(Motivation)
- 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
- 如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?
C++ 中构造函数你调用虚函数是静态绑定。因为派生类的构造函数先调用基类的构造函数。
模式定义
将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)。 ——《设计模式》GoF
代码示例
#include <iostream>
using namespace std;
class House
{
public:
void Init()
{
BuildPart1();
// 建四个窗
for (int i = 0; i < 4; i++) {
BuildPart2();
}
bool flag = BuildPart3();
if (flag) {
BuildPart4();
}
BuildPart5();
}
virtual ~House(){}
protected:
virtual void BuildPart1() = 0;
virtual void BuildPart2() = 0;
virtual bool BuildPart3() = 0;
virtual void BuildPart4() = 0;
virtual void BuildPart5() = 0;
};
class StoneHouse: public House
{
protected:
virtual void BuildPart1()
{
cout << "part" << 1 << endl;
}
virtual void BuildPart2()
{
cout << "part" << 2 << endl;
}
virtual bool BuildPart3()
{
cout << "part" << 3 << endl;
return true;
}
virtual void BuildPart4()
{
cout << "part" << 4 << endl;
}
virtual void BuildPart5()
{
cout << "part" << 5 << endl;
}
};
int main()
{
House *pHouse = new StoneHouse;
pHouse->Init(); // 完成构建。 C++ 中构造函数里面的虚函数调用是静态绑定的,所以这里用 Init 函数。
getchar();
return 0;
}
输出:
part1
part2
part2
part2
part2
part3
part4
part5
修改版,根据自己理解写的,不太确定是不是这个意思:
#include <iostream>
#include <string>
using namespace std;
// 抽象基类
class House {
public:
void showInfo()
{
cout << one << two << three << four << five << endl;
}
virtual void Do() = 0;
protected:
string one;
string two;
string three;
string four;
string five;
};
// 抽象基类
class HouseBuilder {
public:
House* GetResult() {
return pHouse;
}
virtual ~HouseBuilder() {}
HouseBuilder(House *house) :pHouse(house)
{
}
protected:
House* pHouse;
public:
virtual void BuildPart1() = 0;
virtual void BuildPart2() = 0;
virtual bool BuildPart3() = 0;
virtual void BuildPart4() = 0;
virtual void BuildPart5() = 0;
};
class StoneHouse : public House {
public:
virtual void Do()
{
cout << "石头房:";
showInfo();
}
friend class StoneHouseBuilder;
};
class StoneHouseBuilder : public HouseBuilder {
public:
StoneHouseBuilder(House *house) :HouseBuilder(house) {}
protected:
virtual void BuildPart1() {
StoneHouse* p = static_cast<StoneHouse*>(pHouse); // 友元不能继承?
p->one = "一座屋,";
}
virtual void BuildPart2() {
StoneHouse* p = static_cast<StoneHouse*>(pHouse);
p->two += "两间房,";
}
virtual bool BuildPart3() {
StoneHouse* p = static_cast<StoneHouse*>(pHouse);
p->three = "三扇门,";
return true;
}
virtual void BuildPart4() {
StoneHouse* p = static_cast<StoneHouse*>(pHouse);
p->four = "四个窗,";
}
virtual void BuildPart5() {
StoneHouse* p = static_cast<StoneHouse*>(pHouse);
p->five = "五张桌。";
}
};
class HouseDirector {
HouseBuilder* pHouseBuilder;
public:
HouseDirector(HouseBuilder* pHouseBuilder) {
this->pHouseBuilder = pHouseBuilder;
}
House* Construct()
{
pHouseBuilder->BuildPart1();
for (int i = 0; i < 4; i++) {
pHouseBuilder->BuildPart2();
}
bool flag = pHouseBuilder->BuildPart3();
if (flag) {
pHouseBuilder->BuildPart4();
}
pHouseBuilder->BuildPart5();
return pHouseBuilder->GetResult();
}
};
int main()
{
StoneHouse stoneHouse;
StoneHouseBuilder stoneHouseBuilder(&stoneHouse);
HouseDirector houseDirector(&stoneHouseBuilder);
House* myHouse = houseDirector.Construct();
myHouse->Do();
getchar();
return 0;
}
输出:
石头房:一座屋,两间房,两间房,两间房,两间房,三扇门,四个窗,五张桌。
类图
要点总结
- Builder 模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
- 变化点在哪里,封装哪里—— Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。
- 在Builder模式中,要注意不同语言中构造器内调用虚函数的差别(C++ vs. C#) 。
参考:GeekBand
标签:StoneHouse,House,void,pHouseBuilder,virtual,构建,模式,Builder From: https://www.cnblogs.com/huvjie/p/16734667.html