Builder构建器
动机(Motivation)
在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这份复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而变化?
示例1
#pragma once
class House {
public:
//此处不能在构造函数内处理
void Inti() {
this->BuildPart1();//构造函数不能调用虚函数
for (int i = 0; i < 4; ++i)
{
this->BuildPart2();
}
bool flag = this->BuildPart3();
if (flag){
this->BuildPart4();
}
this->BuildPart4();
}
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() {
}
virtual void BuildPart2() {
}
virtual bool BuildPart3() {
return true;
}
virtual void BuildPart4() {
}
virtual void BuildPart5() {
}
};
void mian()
{
House* house = new StoneHouse();
house->Inti();
}
示例2
#pragma once
class House {
//...
};
class HouseBuilder {
public:
House* GetResult() {
return house_;
}
virtual ~HouseBuilder() {}
protected:
House* house_;
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 {
//...
};
class StoneHouseBuilder : public HouseBuilder {
protected:
virtual void BuildPart1() {
//...
}
virtual void BuildPart2() {
//...
}
virtual bool BuildPart3() {
//...
return true;
}
virtual void BuildPart4() {
//...
}
virtual void BuildPart5() {
//...
}
};
class HouseDrector {
public:
HouseBuilder* house_builder_;
HouseDrector(HouseBuilder* house_builder)
: house_builder_(house_builder)
{}
House* Construct(){
house_builder_->BuildPart1();
for (int i = 0; i < 4; ++i)
{
house_builder_->BuildPart2();
}
bool flag = house_builder_->BuildPart3();
if (flag) {
house_builder_->BuildPart4();
}
house_builder_->BuildPart4();
return house_builder_->GetResult();
}
};
void mian()
{
HouseBuilder* house_builder = new StoneHouseBuilder();
HouseDrector* house_drector = new HouseDrector(house_builder);
House* house = house_drector->Construct();
}
要点总结
Builder模式主要用于“分步骤构建一个复杂的对象“。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
变化点在哪里,封装哪里---Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。
在Builder模式中,要注意不同语言构造器内调用虚函数的差别。