【设计模式】创建型模式之生成器Builder

生成器Builder是一种创建型设计模式,意在将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

下面是Builder模式的类图——

Builder:为创建一个Product对象的各个部件指定抽象接口。

ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,提供一个检索产品的接口。

Director:构造一个使用Builder接口的对象。

Product:表示被构造的复杂对象,ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

这里写图片描述

当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时,或者当构造过程必须允许被构造的对象有不同的表示时,我们就可以尝试使用Builder模式了。从上面的类图中可以看出,客户创建Director对象,并用它所想要的Builder对象进行配置,一旦产品部件被生成,Director就会通知Builder,Builder处理Director的请求,并将部件添加到该产品中,客户从Builder中检索产品。Builder模式的好处就是只是提供给Director一个构造产品的抽象接口,却隐藏了这个产品的表示和内部结构,同时也隐藏了该产品是如何装配的,因此可以让我们改变一个产品的内部表示,将构造代码和表示代码分开,对构造过程进行更精细的控制。

下面是一个使用了Builder模式的例子。

class Engine;
class Classis;
class Body;
class ElectricalEquipment;

class Car
{
public:
    Car() : m_pEngine(0), m_pClassis(0), m_pBody(0), m_pEquipment(0) {}

    void addEngine(Engine *engine) { m_pEngine = engine; }
    void addClassis(Classis *classis) { m_pClassis = classis; }
    void addBody(Body *body) { m_pBody = body; }
    void addElectricalEquipment(ElectricalEquipment *equipment) { m_pEquipment = equipment; }

private:
    Engine *m_pEngine;
    Classis *m_pClassis;
    Body *m_pBody;
    ElectricalEquipment *m_pEquipment;
};

class Engine {};
class Classis {};
class Body {};
class ElectricalEquipment {};

class CarBuilder
{
public:
    virtual void buildCar() {}
    virtual void buildEngine() {}
    virtual void buildClassis() {}
    virtual void buildBody() {}
    virtual void buildElectricalEquipment() {}

    virtual Car* getCar() { return 0; }

protected:
    CarBuilder() {}
};

class NormalCarBuilder : public CarBuilder
{
public:
    NormalCarBuilder() : m_pCar(0) {}

    void buildCar() { m_pCar = new Car; }
    void buildEngine() { m_pCar ? m_pCar->addEngine(new Engine) : (void)0; }
    void buildClassis() { m_pCar ? m_pCar->addClassis(new Classis) : (void)0; }
    void buildBody() { m_pCar ? m_pCar->addBody(new Body) : (void)0; }
    void buildElectricalEquipment() { m_pCar ? m_pCar->addElectricalEquipment(new ElectricalEquipment) : (void)0; }

    Car* getCar() { return m_pCar; }

private:
    Car* m_pCar;
};

class CarClient
{
public:
    Car* createCar(CarBuilder *builder)
    {
        if (builder) {
            builder->buildCar();
            builder->buildEngine();
            builder->buildClassis();
            builder->buildBody();
            builder->buildElectricalEquipment();

            return builder->getCar();
        }

        return 0;
    }
};

测试代码如下:

    CarClient cc;
    NormalCarBuilder ncb;
    cc.createCar(&nbcb);

例子中,CarBuilder类对应于类图中的Builder,定义了构造Car的几个接口,分别是汽车本身以及汽车的的发动机、地盘、车身、电气设备,还提供了一个获取最终Car的接口,这些函数都是virtual函数,这是必须的,当然也可以根据需要声明为纯虚函数。NormalCarBuilder类对应于类图中的ConcreteBuilder,具体实现了构造Car的接口,还保存了Car作为成员变量。ClientCar类对应于类图中的Director,其成员函数createCar对应于Director::construct,参数为指向Builder的指针,用于构造Car及其所有零部件,最后通过getCar获取构造完成的Car。Car是我们最终的产品,它包括了四个部分:发动机、地盘、车身、电气设备。当我们开始创建Car的时候,只需实例化NormalCarBuilder,把这个实例化对象作为参数传给ClientCar::createCar即可。可见,当一个产品有不同的零部件时,想要分离或隐藏产品的表示及装配时,使用Builder模式恰到好处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值