• 建造者模式


    建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。这是建造者模式的标准表达,不过看着让人迷惑,什么叫构建和表示的分离?一个对象使用构造函数构造之后不就固定了,只有通过它方法来改变它的属性吗?而且还要同样的构建过程搞出不同的表示,怎么可能呢?多写几个构造函数?

    其实多写几个构造函数,根据不同参数设置对象不同的属性,也可以达到这样的效果,只是这样就非常麻烦了,每次要增加一种表示就要添加一个构造函数,将来构造函数会多得连自己都不记得了,这违背了开放-封闭的原则。

    要不就只能设计几个set函数,每次属性不一样了,我就构造一个对象,然后用set函数改变对象的属性。这样也可以达到效果。只是代码就会非常冗余了,每个要用到这个对象的地方,都要写上好几句语句,一旦对象有点什么变化,还得到处都改一遍,这样就很容易出错,以后别人看着这种神逻辑和神代码估计也会崩溃了。而且这也违背了依赖倒转的原则。

    于是大神们就开始想了,不能加很多构造函数,也不能直接用一堆set函数,然后发现,有些对象的构建是固定的几个步骤的,就像一条流水线一样,任何的产品都是通过每一个固定的步骤拼凑出来的。例如说一部手机,先放主板,再放屏幕,再放电池,再放外壳,贴个膜就能卖几千了,每次推出新产品,就换个更好的主板,换个大点的屏幕,再整个大容量电池,贴个超牛B的高透膜,又能卖出个新价钱。就是说,这些步骤都没有变,变的只是每个部分的东西。

    这就是大神的厉害之处了,透过现象看本质,基本有变的,有不变的,那敢情好,面向对象的一个重要指导思想就是,封装隔离变化的,留出不变的。于是他们就用一个Builder类把步骤中的每个部分封装起来,这个类的主要作用就是生产每个部件,再抽象一下提升高度,这样就依赖倒转了,这样每次只需要添加一个类,这个类还是这几个部分,只是内部的实现已经不一样了,这样就满足了开放-封闭的原则了。但还是有一个问题,光有Builder类还不行,虽然产品的每个部分都有对应的函数,但是用起来的话,还是跟前面说的set函数一样,一用就要使用一大堆函数,也就是这变的东西是封装起来了,但这不变的东西还没留出来。这时,就添加一个Director类,这个类就是专门规定组装产品的步骤的,这样只要告诉Director使用哪个Builder,就能生产出不同的产品,对于客户端来说,只看到用了Director的一个construct函数,甚是方便。

    再反过来看建造者模式的定义,构建指的就是生产一个产品的步骤,表示就是每个产品部分的具体实现,通过Director封装步骤,通过Builder封装产品部分的实现,再把他两隔离开,就能隔离变的,留出不变的供客户端使用。

    Builder.h
    
    #ifndef _BUILDER_H_
    #define _BUILDER_H_
    
    #include <stdio.h>
    
    class Product{
    public:
        Product();
        ~Product();
    
        void setPartA(int param);
        void setPartB(int param);
        void setPartC(int param);
    
        void show();
    
    private:
        int partA;
        int partB;
        int partC;
    
    };
    
    
    class AbstractBuilder{
    public:
        AbstractBuilder();
        virtual ~AbstractBuilder();
    
        virtual void createProduct() = 0;
        virtual void buildPartA(int param) = 0;
        virtual void buildPartB(int param) = 0;
        virtual void buildPartC(int param) = 0;
    
        virtual Product* getProduct() = 0;
    };
    
    
    class Builder: public AbstractBuilder{
    public:
        Builder();
        ~Builder();
    
        void createProduct();
        void buildPartA(int param);
        void buildPartB(int param);
        void buildPartC(int param);
    
        Product* getProduct();
    
    private:
        Product* curProduct;
    
    };
    
    #endif
     
    
    Builder.cpp
    
    #include "Builder.h"
    
    
    
    Product::Product()
    {
    
    }
    
    
    Product::~Product()
    {
    
    }
    
    
    void Product::setPartA(int param)
    {
        partA = param;
    }
    
    
    void Product::setPartB(int param)
    {
        partB = param;
    }
    
    
    void Product::setPartC(int param)
    {
        partC = param;
    }
    
    
    void Product::show()
    {
        fprintf(stderr,"partA = %d  partB = %d  partC = %d
    ",partA,partB,partC);
    }
    
    
    AbstractBuilder::AbstractBuilder()
    {
    
    }
    
    
    AbstractBuilder::~AbstractBuilder()
    {
    
    }
    
    
    Builder::Builder()
    :curProduct(NULL)
    {
    
    }
    
    
    Builder::~Builder()
    {
    
    }
    
    
    void Builder::createProduct()
    {
        fprintf(stderr,"创建一个产品空壳
    ");
        curProduct = new Product();
    }
    
    
    void Builder::buildPartA(int param)
    {
        fprintf(stderr,"正在构建产品的A部分
    ");
        curProduct->setPartA(param);
    }
    
    
    void Builder::buildPartB(int param)
    {
        fprintf(stderr,"正在构建产品的B部分
    ");
        curProduct->setPartB(param);
    }
    
    
    void Builder::buildPartC(int param)
    {
        fprintf(stderr,"正在构建产品的C部分
    ");
        curProduct->setPartC(param);
    }
    
    
    Product* Builder::getProduct()
    {
        //我的理解就是产品交出去之后,怎么释放怎么弄就不归建造者管了
        return curProduct;
    }
     
    
    Director.h
    
    #ifndef _DIRECTOR_H_
    #define _DIRECTOR_H_
    
    #include "Builder.h"
    
    class Director
    {
    public:
        Director(AbstractBuilder* builder);
        ~Director();
    
        void construct();
    
    private:
        AbstractBuilder* curBuilder;
    };
    
    #endif
     
    
    Director.cpp
    
    
    #include "Director.h"
    
    
    Director::Director(AbstractBuilder* builder)
    {
        curBuilder = builder;
    }
    
    
    Director::~Director()
    {
    
    }
    
    
    void Director::construct()
    {
        if (!curBuilder)
            return;
    
        curBuilder->createProduct();
        curBuilder->buildPartA(1);
        curBuilder->buildPartB(2);
        curBuilder->buildPartC(3);
    }
    client.cpp
    
    #include "Director.h"
    
    
    
    int main()
    {
        AbstractBuilder* builder = new Builder();
        Director* director = new Director(builder);
    
        director->construct();
        
        Product* product = builder->getProduct();
        product->show();
        return 0;
    }

  • 相关阅读:
    libPods.a 无法找到的解决方法
    Mac 必备软件 Quicksilver
    Mac玩老游戏DOOM II
    [转载]The Island Castaway mac版解锁
    看了不到一半同事上培训班时候的示例代码,解决了很多前几个月遇到的问题。
    8月16日 layui使用
    8月14日
    8月13日
    8月12日
    8月9日
  • 原文地址:https://www.cnblogs.com/boost/p/10542125.html
Copyright © 2020-2023  润新知