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

来源:互联网 发布:mac os10.7.5如何升级 编辑:程序博客网 时间:2024/05/19 01:09

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");}
原创粉丝点击