作者:明年夏天1314520 | 来源:互联网 | 2023-06-06 16:11
1、定义:建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的对象。2、使用场景:产品的表示比较复杂,构建一个产品,需要暴露太多产品的属性。这时候可以通
1、定义:
建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的对象。
2、使用场景:
- 产品的表示比较复杂,构建一个产品,需要暴露太多产品的属性。这时候可以通过一个建造某一种特殊类型产品的的建造者来封装。(前面是一个工厂模式。为了容易扩展,引入抽象建造者和指挥者这两个角色)
- 建造过程比较固定,建造的顺序一定;
3、结构图:
上面一幅图可以用包工头与工人、工人甲、工人乙类似的关系来描述。
包工头就是其中的Director,工人就是Builder,工人甲与工人乙就是具体的建造类ConcreteBuilder。
construct可以返回一个产品,也可以不返回,通过调用具体构建类的”GetProduct()”方法,返回子类中产品。产品句柄在ConcreteBuilder类中。
4、组成:
- 产品类:一般是一个较复杂的对象;
- 抽象建造者:统一产品构建方式,为扩展用。一般有两类抽象方法,一类方法用来建造对象,这一类的方法每一个用来建造产品的不同部分,一类方法用来返回建造的对象;
- 具体建造者:实现抽象建造者所有未实现的方法;
指挥者:有一个Construct(param)方法,该方法的参数是抽象建造者,用来接收具体的建造者对象。该方法统一了对象的建造步骤及建造顺序。
抽象建造者的用途
- 规范了产品建造的步骤(反映了产品的组成);
- 便于扩展系统;
指挥者的用途
- 隔离了客户与产品的创建过程;
- 控制产品的创建过程(或者说创建流程、创建顺序);
5、使用优点:
- 在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
- 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象 。
- 可以更加精细地控制产品的创建过程 ,将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
- 增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭原则”。
一类产品,要有一个抽象建造者,若干个具体建造者,用来建造不同表示(组成)的该类型产品。
6、举例:
下面这个例子以肯德基为例,说明在肯德基中不同顾客点了不同的套餐的场景:
服务员(Director)创建不同的套餐(ConcreteBuilder),创建套餐可以分为创建吃的(BuildPartA),创建喝的(BuildPartB)。
顾客A点了汉堡和雪碧 –》 则具体实现类可以设计为
class ConcreteBuilder_Hanbao_Xuebi : public Builder {
pulic:
BuilderFood() { 添加汉堡; }
BuilderDrink() { 添加雪碧; }
};
顾客B点了鸡肉和可乐 –》 则具体实现类可以设计为
class ConcreteBuilder_Jirou_Kele : public Builder {
pulic:
BuilderFood() { 添加鸡肉; }
BuilderDrink() { 添加可乐; }
};
总结:
一般来说,如果产品的建造很复杂,那么请用工厂模式;如果产品的建造更复杂,那么请用建造者模式。
下面的BuilderPattern.cpp是具体使用建造者模式的代码,里面体现了建造者模式中几个组成对象的关系。
#include
class Wheel
{};
class Body
{};
class Car
{
public:
virtual void BuildupWheel(const Wheel& wheel) = 0;
virtual void BuildupBody(const Body& body) = 0;
protected:
Wheel _wheel;
Body _body;
};
class Ferrari : public Car
{
public:
virtual void BuildupWheel(const Wheel& wheel) override
{
_wheel = wheel;
std::cout <<"this is the way of buildup wheel of Ferrari" < }
virtual void BuildupBody(const Body& body) override
{
_body = body;
std::cout <<"this is the way of buildup body of Ferrari" < }
};
class RollsRoyce : public Car
{
public:
virtual void BuildupWheel(const Wheel& wheel) override
{
_wheel = wheel;
std::cout <<"this is the way of buildup wheel of RollsRoyce" < }
virtual void BuildupBody(const Body& body) override
{
_body = body;
std::cout <<"this is the way of buildup body of RollsRoyce" < }
};
class Builder
{
public:
virtual void BuildupWheel(const Wheel& wheel) = 0;
virtual void BuildupBody(const Body& body) = 0;
virtual Car* GetProduct() = 0;
};
class ConcreteBuilderFerrari : public Builder
{
public:
ConcreteBuilderFerrari() { _pCar = new Ferrari(); }
virtual void BuildupWheel(const Wheel& wheel) { _pCar->BuildupWheel(wheel); }
virtual void BuildupBody(const Body& body) { _pCar->BuildupBody(body); }
virtual Car* GetProduct() { return _pCar; }
private:
Car* _pCar;
};
class ConcreteBuilderRollsRoyce : public Builder
{
public:
ConcreteBuilderRollsRoyce() { _pCar = new RollsRoyce(); }
virtual void BuildupWheel(const Wheel& wheel) { _pCar->BuildupWheel(wheel); }
virtual void BuildupBody(const Body& body) { _pCar->BuildupBody(body); }
virtual Car* GetProduct() { return _pCar; }
private:
Car* _pCar;
};
class Director
{
public:
void Consturct(Builder* builder)
{
builder->BuildupWheel(Wheel());
builder->BuildupBody(Body());
}
};
int main(int argc, char* argv[])
{
Director* director = new Director;
Builder* ferrariBuilder = new ConcreteBuilderFerrari;
Builder* rollsRoyceBuilder = new ConcreteBuilderRollsRoyce;
director->Consturct(ferrariBuilder);
director->Consturct(rollsRoyceBuilder);
Ferrari* ferrari = static_cast(ferrariBuilder->GetProduct());
RollsRoyce* rollsRoyce = static_cast(rollsRoyceBuilder->GetProduct());
system("pause");
}