Builder(建造者)模式

案例: 用户需要建造一个别墅和一个民居。

  将别墅和民居的组成都抽象为一个门,一个墙和一个地面,建造别墅时分别是建造”别墅的门”、”别墅的墙”、”别墅的地面”,建造民居时则分别是建造”民居的门”、”民居的墙”、”民居的地面”。最简单的实现为:

class House
{
public:
    void setFloor(string floor) { m_floor = floor; }    //建造地面
    void setWall(string wall) { m_wall = wall; }        //建造墙
    void setDoor(string door) { m_door = door; }        //建造门

    void outFloor() { cout << m_floor << endl; }
    void outWall() { cout << m_wall << endl; }
    void outDoor() { cout << m_door << endl; }

private:
    string m_floor;
    string m_wall;
    string m_door;
};

int main(void)
{
    //用户自己建造别墅
    House* ph1 = new House;
    ph1->setDoor("villa door");
    ph1->setWall("villa wall");
    ph1->setFloor("villa floor");
    ph1->outFloor();
    ph1->outWall();
    ph1->outDoor();
    delete ph1;

    //用户自己建造民居
    House* ph2 = new House;
    ph2->setWall("citizen wall");
    ph2->setDoor("citizen door");
    ph2->setFloor("citizen floor");
    ph2->outFloor();
    ph2->outWall();
    ph2->outDoor();
    delete ph2;

    return 0;
}

  这种写法,显然用户代码和对象的构造耦合性太强,①用户在构建对象时需要考虑构建的逻辑(先建造墙还是先建造门等),②一旦对象发生改变对用户影响太大。要实现被构建的对象和用户代码的解耦合,用户代码可以”请一支工程队来建造房子”:

class House
{
public:
    void setFloor(string floor) { m_floor = floor; }    //建造地面
    void setWall(string wall) { m_wall = wall; }        //建造墙
    void setDoor(string door) { m_door = door; }        //建造门

    void outFloor() { cout << m_floor << endl; }
    void outWall() { cout << m_wall << endl; }
    void outDoor() { cout << m_door << endl; }

private:
    string m_floor;
    string m_wall;
    string m_door;
};

//负责建造别墅的施工队
class VillaBuild
{
public:
    VillaBuild() : m_house(new House) {}

    void makeBulid() { buildDoor(); buildWall(); buildFloor(); }

    void buildDoor() { m_house->setDoor("villa door"); }
    void buildWall() { m_house->setWall("villa wall"); }
    void buildFloor() { m_house->setFloor("villa floor"); }

    House* getHouse() { return m_house; }

private:
    House* m_house;
};

int main(void)
{
    House* ph1 = new House;
    VillaBuild* build = new Build;  //请工程队建造别墅
    build->makeBulid();             //执行建造房子操作
    ph1 = build->getHouse();

    ph1->outFloor();
    ph1->outWall();
    ph1->outDoor();

    delete ph1;
    delete build;

    return 0;
}

  上面代码可用下面UML表示:
这里写图片描述
  VillaBuild类只能负责建造别墅,显然,我们需要对VillaBuild进行抽象:定义抽象基类Buileder,其派生类可以实例化为建造别墅的VillaBuilder施工队、建造民居的CitizenBuilder施工队等,但是注意,建造别墅和建造民居的逻辑(在这里体现为先建造门还是先建造墙等)肯定是不同的,所以需要再增加一个类–设计者,用于控制施工队的建造逻辑。UML图为:
这里写图片描述
  这就是建造者模式,它由4个角色组成:
  (1)Builder: 统一抽象接口,定义为产品(房子)创建各个部分的虚函数
  (2)VillaBuild: 创建产品各个部分的具体实现
  (3)Director: 调用Builder的接口对象中的函数,正确构建产品
  (4)House: 即产品,表示被建造的复杂对象
  建造者模型适用于将一个对象的构建和对象的使用进行分离的情景。(对象的构建就是要使得该对象可用所要进行的设置步骤,对象的使用即是对对象的正常使用)。

//房子(产品)
class House
{
public:
    void setFloor(string floor) { m_floor = floor; }    //建造地面
    void setWall(string wall) { m_wall = wall; }        //建造墙
    void setDoor(string door) { m_door = door; }        //建造门

    void outFloor() { cout << m_floor << endl; }
    void outWall() { cout << m_wall << endl; }
    void outDoor() { cout << m_door << endl; }

private:
    string m_floor;
    string m_wall;
    string m_door;
};

//施工队抽象类
class Builder
{
public:
    virtual void buildDoor() = 0;
    virtual void buildWall() = 0;
    virtual void buildFloor() = 0;
    virtual House* getHouse() = 0;
};

//建造别墅的施工队
class VillaBuild : public Builder
{
public:
    VillaBuild() : m_house(new House) {}
    void buildDoor() { m_house->setDoor("villa door"); }
    void buildWall() { m_house->setWall("villa wall"); }
    void buildFloor() { m_house->setFloor("villa floor"); }
    House* getHouse() { return m_house; }

private:
    House* m_house;
};

//建造民房的施工队
class CitizenBuilder : public Builder
{
public:
    CitizenBuilder() : m_house(new House) {}
    void buildDoor() { m_house->setDoor("citizen door"); }
    void buildWall() { m_house->setWall("citizen wall"); }
    void buildFloor() { m_house->setFloor("citizen floor"); }
    House* getHouse() { return m_house; }

private:
    House* m_house;
};

//设计师,负责指挥施工队
class Director
{
public:
    Director(Builder* build) : m_build(build){}
    void Construct()
    {
        m_build->buildWall();
        m_build->buildFloor();
        m_build->buildDoor();
    }

private:
    Builder* m_build;
};


int main(void)
{
    Director *dir = NULL;
    CitizenBuilder *cb = NULL;
    House *ph = NULL;

    //指定建造民房的施工队并交付设计师指挥
    cb = new CitizenBuilder;
    dir = new Director(cb);
    dir->Construct();   //设计师指挥建造房子操作
    ph = cb->getHouse();

    ph->outFloor();
    ph->outWall();
    ph->outDoor();

    delete cb;
    delete dir;
    delete ph;

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值