设计模式:创建型模式:建造模式(Builder Pattern)

来源:互联网 发布:胡歌人品知乎 编辑:程序博客网 时间:2024/05/01 01:04

本文是下面文章的剪辑,深表感谢:

1)Builder模式的误区:将复杂对象的构建进行封装,就是Builder模式了吗? http://www.cnblogs.com/happyhippy/archive/2010/09/01/1814287.html

2)深入浅出设计模式 by AI92

3)Example of `builder' design pattern in C++  https://gist.github.com/pazdera/1121152



根据UML,整个过程有4个类参与

1)抽象建造者角色:这个角色用来规范产品对象的各个组成成分的建造。一般而言,此角色独立于应用程序的业务逻辑;

2)具体建造者角色:担任这个角色的是于应用程序紧密相关的类,它们在指导者的调用下创建产品实例。这个角色在实现抽象建造者角色提供的方法的前提下,达到完成产品组装,提供成品的功能;

3)指导者角色:调用具体建造者角色以创建产品对象。指导者并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者对象。

4)产品角色:建造中的复杂对象。它要包含那些定义组件的类,包括将这些组件装配成产品的接口。

首先客户程序创建一个指导者对象,一个建造者角色,并将建造者角色传入指导者对象进行配置。然后,指导者按照步骤调用建造者的方法创建产品。最后客户程序从建造者或者指导者那里得到产品。 从建造模式的工作流程来看,建造模式将产品的组装“外部化”到了建造者角色中来。这是和任何正规的工厂模式不一样的——产品的创建是在产品类中完成的。

代码例子:车

/*

* Example of `builder' design pattern.
* Copyright (C) 2011 Radek Pazdera
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <string>
/* Car parts */
class Wheel
{
public:
    int size;
};
class Engine
{
public:
    int horsepower;
};
class Body
{
public:
    std::string shape;
};
/* Final product -- a car */
class Car
{
public:
    Wheel* wheels[4];
    Engine* engine;
    Body* body;
    void specifications()
    {
        std::cout << "body:" << body->shape << std::endl;
        std::cout << "engine horsepower:" << engine->horsepower << std::endl;
        std::cout << "tire size:" << wheels[0]->size << "'" << std::endl;
    }
};
/* Builder is responsible for constructing the smaller parts */
class Builder
{
public:
    virtual Wheel* getWheel() = 0;
    virtual Engine* getEngine() = 0;
    virtual Body* getBody() = 0;
};
/* Director is responsible for the whole process */
class Director
{
private:
    Builder* builder;
public:
    void setBuilder(Builder* newBuilder)
    {
        builder = newBuilder;
    }
    Car* getCar()
    {
        Car* car = new Car();
        car->body = builder->getBody();
        car->engine = builder->getEngine();
        car->wheels[0] = builder->getWheel();
        car->wheels[1] = builder->getWheel();
        car->wheels[2] = builder->getWheel();
        car->wheels[3] = builder->getWheel();
        return car;
    }
};
/* Concrete Builder for Jeep SUV cars */
class JeepBuilder : public Builder
{
public:
    Wheel* getWheel()
    {
        Wheel* wheel = new Wheel();
        wheel->size = 22;
        return wheel;
    }
    Engine* getEngine()
    {
        Engine* engine = new Engine();
        engine->horsepower = 400;
        return engine;
    }
    Body* getBody()
    {
        Body* body = new Body();
        body->shape = "SUV";
        return body;
    }
};
/* Concrete builder for Nissan family cars */
class NissanBuilder : public Builder
{
public:
    Wheel* getWheel()
    {
        Wheel* wheel = new Wheel();
        wheel->size = 16;
        return wheel;
    }
    Engine* getEngine()
    {
        Engine* engine = new Engine();
        engine->horsepower = 85;
        return engine;
    }
    Body* getBody()
    {
        Body* body = new Body();
        body->shape = "hatchback";
        return body;
    }
};
int main()
{
    Car* car; // Final product
    /* A director who controls the process */
    Director director;
    /* Concrete builders */
    JeepBuilder jeepBuilder;
    NissanBuilder nissanBuilder;
    /* Build a Jeep */
    std::cout << "Jeep" << std::endl;
    director.setBuilder(&jeepBuilder); // using JeepBuilder instance
    car = director.getCar();
    car->specifications();
    std::cout << std::endl;
    /* Build a Nissan */
    std::cout << "Nissan" << std::endl;
    director.setBuilder(&nissanBuilder); // using NissanBuilder instance
    car = director.getCar();
    car->specifications();
    return 0;
}


 感悟:

其实director知道product的组成是什么样的,比如说知道car有body, engine, wheels。但是director不知道是具体是什么body engine wheels。

不过builder知道,利用多态实现不同的产品

0 0
原创粉丝点击