建造者模式——设计模式之创建型

1、定义:

建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的对象。

2、使用场景:

  1. 产品的表示比较复杂,构建一个产品,需要暴露太多产品的属性。这时候可以通过一个建造某一种特殊类型产品的的建造者来封装。(前面是一个工厂模式。为了容易扩展,引入抽象建造者和指挥者这两个角色)
  2. 建造过程比较固定,建造的顺序一定;

3、结构图:

这里写图片描述

上面一幅图可以用包工头与工人、工人甲、工人乙类似的关系来描述。

包工头就是其中的Director,工人就是Builder,工人甲与工人乙就是具体的建造类ConcreteBuilder。

construct可以返回一个产品,也可以不返回,通过调用具体构建类的”GetProduct()”方法,返回子类中产品。产品句柄在ConcreteBuilder类中。

4、组成:

  1. 产品类:一般是一个较复杂的对象;
  2. 抽象建造者:统一产品构建方式,为扩展用。一般有两类抽象方法,一类方法用来建造对象,这一类的方法每一个用来建造产品的不同部分,一类方法用来返回建造的对象;
  3. 具体建造者:实现抽象建造者所有未实现的方法;
  4. 指挥者:有一个Construct(param)方法,该方法的参数是抽象建造者,用来接收具体的建造者对象。该方法统一了对象的建造步骤及建造顺序。

    抽象建造者的用途

    • 规范了产品建造的步骤(反映了产品的组成);
    • 便于扩展系统;

    指挥者的用途

    • 隔离了客户与产品的创建过程;
    • 控制产品的创建过程(或者说创建流程、创建顺序);

5、使用优点:

  1. 在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
  2. 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象 。
  3. 可以更加精细地控制产品的创建过程 ,将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
  4. 增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭原则”。

一类产品,要有一个抽象建造者,若干个具体建造者,用来建造不同表示(组成)的该类型产品。

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是具体使用建造者模式的代码,里面体现了建造者模式中几个组成对象的关系。

/*!
 * \file    BuilderPattern.cpp
 * \date    2017/08/07 21:00
 * \author  common
 *
 * \brief   简要介绍建造者模式的使用
 */

#include <iostream>

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" << std::endl;
    }

    virtual void BuildupBody(const Body& body) override
    {
        _body = body;
        std::cout << "this is the way of buildup body of Ferrari" << std::endl;
    }
};

// 具体产品,劳斯莱斯
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" << std::endl;
    }

    virtual void BuildupBody(const Body& body) override
    {
        _body = body;
        std::cout << "this is the way of buildup body of RollsRoyce" << std::endl;
    }
};

//////////////////////////////////////////////////////////////////////////

// 抽象构建类
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<Ferrari*>(ferrariBuilder->GetProduct());
    RollsRoyce* rollsRoyce = static_cast<RollsRoyce*>(rollsRoyceBuilder->GetProduct());

    system("pause");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值