• 第26章 创建型模式大PK


    26.1 工厂方法模式 VS 建造者模式

    26.1.1 按工厂方法建造超人

    (1)产品:两类超人,成年超人和未成年超人。

    (2)工厂:这里选择简单工厂

    【编程实验】工厂方法建造超人

    //创建型模式大PK——工厂方法和建造者模式
    //实例:利用简单工厂创建的超人
    #include <iostream>
    using namespace std;
    
    //***************************抽象产品接口*********************
    //超人接口
    class ISuperMan
    {
    public:
        //每个超人都有特殊的技能
        virtual void specialTalent() = 0;
    
        virtual ~ISuperMan(){}
    };
    
    //*************************具体产品***********************
    //成年超人
    class AdultSuperMan : public ISuperMan
    {
    public:
        void specialTalent()
        {
            cout << "超人力大无穷" <<endl;
        }
    };
    
    //未成年人超人
    class ChildSuperMan : public ISuperMan
    {
    public:
        void specialTalent()
        {
            cout << "小超人的能力是刀枪不入、快速移动" <<endl;
        }
    };
    
    //***********************简单工厂****************************
    class SuperManFactory
    {
    public:
        static ISuperMan* createSuperMan(string type)
        {
            //根据输入参数产生不同的超人
            if(type == "adult")
            {
                return new AdultSuperMan();
            }
            else if (type == "child")
            {
                return new ChildSuperMan();
            }
            else
                return NULL;
        }
    };
    
    int main()
    {
        //模拟生产超人(注意从生产工厂里出来的产品(如adult)都是一个模
        //样的,没有特殊的地方,这与后面的建造者模式有很大的不同)
        ISuperMan* sm = SuperManFactory::createSuperMan("child");
        //展示一下超人的技能
        sm->specialTalent();
    
        delete sm;
    
        return 0;
    };

    26.1.2 按建造者模式建造超人

    (1)产品的三大组成部分:躯体、特殊技能、身份标记

    (2)建造者:Builder。注意,与标准的建造者模式不同,这里的部件如何组装的过程由各个具体的建造者负责,而标准的作法是放到Director角色中去完成的。

    //创建型模式大PK——工厂方法和建造者模式
    //实例:利用建造者模式创建的超人
    #include <iostream>
    using namespace std;
    
    //***************************辅助类*********************
    //超人的身驱
    class Body
    {
        string body;
    public:
        string& getBody(){return body;}
        void setBody(string value)
        {
            body = value;
        }
    };
    
    //特殊技能
    class SpecialTalent
    {
        string specialTalent;
    public:
        string& getSpecialTalent(){return specialTalent;}
        void setSpecialTalent(string value)
        {
            specialTalent = value;
        }
    };
    
    //超人的标志
    class SpecialSymbol
    {
        string symbol;
    public:
        string& getSymbol(){return symbol;}
        void setSymbol(string value)
        {
            symbol = value;
        }
    };
    
    //超人
    class SuperMan
    {
    private:
        Body body;
        SpecialSymbol specialSymbol;
        SpecialTalent specialTalent;
    public:
        string& getBody(){return body.getBody();}
        void setBody(string value)
        {
            body.setBody(value);
        }
    
        string& getSpecialTalent(){return specialTalent.getSpecialTalent();}
        void setSepcialTalent(string value)
        {
            specialTalent.setSpecialTalent(value);
        }
    
        string& getSpecialSymbol(){return specialSymbol.getSymbol();}
        void setSpecialSymbol(string value)
        {
            specialSymbol.setSymbol(value);
        }
    
        virtual ~SuperMan(){}
    };
    
    //*************************Builder角色***********************
    //抽象建造者
    class Builder
    {
    protected:
        SuperMan* superMan;
    public:
        Builder()
        {
            superMan = new SuperMan();
        }
    
        //构建出超人的躯体
        void setBody(string value)
        {
            superMan->setBody(value);
        }
    
        //构建出超人的特殊技能
        void setSpecialTalent(string value)
        {
            superMan->setSepcialTalent(value);
        }
    
        //构建出超人的特殊标记
        void setSpecialSymbol(string value)
        {
            superMan->setSpecialSymbol(value);
        }
    
        //构建出一个完整的超人
        //超人的各个部件都准备好了,具体怎么组装由实现类来决定,
        //体现建造者模式将复杂对象的构建和表示分离的意图
        virtual SuperMan* getSuperMan() = 0;
    
        virtual ~Builder()
        {
            delete superMan;
        }
    };
    
    //成年超人建造者
    class AdultSuperManBuilder :public Builder
    {
    public:
        SuperMan* getSuperMan()
        {
            //1.标准的建造者模式,建造过程是放在Director中进行装配的。
            //2.建造者模式关注产品的各个部分,甚至构建顺序,
            //  即相同的部件,装配顺序不同,产生的结果也可能不同,
            //  这正是建造者模式的意图)
            superMan->setBody("强壮的躯体");
            superMan->setSepcialTalent("会飞行");
            superMan->setSpecialSymbol("胸前带S标记");
    
            return superMan;
        }
    };
    
    //未成年超人建造者
    class ChildSuperManBuilder :public Builder
    {
    public:
        SuperMan* getSuperMan()
        {
            //建造过程
            superMan->setBody("强壮的躯体");
            superMan->setSepcialTalent("刀枪不入");
            superMan->setSpecialSymbol("胸前带小S标记");
    
            return superMan;
        }
    };
    
    //导演类
    class Director
    {
    private:
        static Builder* adultBuilder;
        static Builder* childBuilder;
    public:
        //本例中,以下函数只是一个空壳,而标准的建造者模式
        //其部件的组装过程是在以下两部函数中完成的!
    
        //建造一个成人超人
        static SuperMan* getAdultSuperMan()
        {
    
            return adultBuilder->getSuperMan();
        }
    
        //建造一个未成年人超人
        static SuperMan* getChildSuperMan()
        {
            return childBuilder->getSuperMan();
        }
    };
    Builder* Director::adultBuilder = new AdultSuperManBuilder();
    Builder* Director::childBuilder = new ChildSuperManBuilder();
    
    int main()
    {
        //建造一个超人
        SuperMan* sm = Director::getAdultSuperMan();
        //SuperMan* sm = Director::getChildSuperMan();
    
        //展示一个超人的能力
        cout << "超人的身体:" << sm->getBody() << endl;
        cout << "超人的特殊能力:" << sm->getSpecialTalent() << endl;
        cout << "超人带的标志:" << sm->getSpecialSymbol() << endl;
    
        return 0;
    };
    /*输出结果
    超人的身体:强壮的躯体
    超人的特殊能力:会飞行
    超人带的标志:胸前带S标记
    */

    26.1.3 最佳实践

    (1)意图不同

      ①工厂方法模式,关注的是一个产品整体无须关心产品各部分是如何创建出来的。

      ②建造者模式,一个具体产品的产生是依赖各个部件的产生以及装配顺序,它关注的是由零件一步一步地组装出产品对象

      ③简单理解,工厂模式是一个对象创建的粗线条应用,建造者模式则是通过细线程勾勒出一个复杂对象,关注的是产品组成部分的创建过程。

    (2)产品的复杂度不同

      ①工厂方法模式创建的产品一般都是单一性质产品,都是一个模样

      ②建造者模式创建的则是一个复合产品,它则各个部件复合而成,部件不同,产品对象当然不同。

      ③一般来说工厂方法模式创建的产品的粒度比较粗,而建造者模式的产品对象粒度比较细。

    (3)方法的选择:如果关注一个产品部件的生产、安装步骤,则选择建造者否则选择工厂方法模式

    26.2 抽象工厂模式 VS 建造者模式

    26.2.1 抽象工厂模式

    (1)产品等级:宝马(BWM)、奔驰(Benz)

    (2)产品族:即车型(如商务车型Van、运动型SUV),即每个工厂要生产两种车型

    【编程实验】按抽象工厂模式生产车辆

     

    //创建型模式大PK——抽象工厂方法和建造者模式
    //实例:利用抽象工厂方法生产汽车
    #include <iostream>
    using namespace std;
    
    //抽象产品
    class  ICar
    {
    public:
        //获取汽车生产商,即品牌
        virtual string getBand() = 0;
        //获取汽车的型号
        virtual string getModel() = 0;
    };
    
    //抽象宝马车
    class AbsBMW : public ICar
    {
       string BMW_BNAD;
    public:
        AbsBMW()
        {
            BMW_BNAD = "宝马汽车";
        }
    
        string getBand()
        {
            return BMW_BNAD;
        }
    };
    
    //宝马商务车
    class BMWVan :public AbsBMW
    {
        string SEVENT_SEARIES;
    public:
        BMWVan():AbsBMW()
        {
            SEVENT_SEARIES = "7系列商务车";
        }
        string getModel()
        {
            return SEVENT_SEARIES;
        }
    };
    
    //宝马Suv
    class BMWSuv :public AbsBMW
    {
        string X_SEARIES;
    public:
        BMWSuv():AbsBMW()
        {
            X_SEARIES = "x系列Suv";
        }
        string getModel()
        {
            return X_SEARIES;
        }
    };
    
    //抽象奔驰车
    class AbsBenz : public ICar
    {
       string BENZ_BNAD;
    public:
        AbsBenz()
        {
            BENZ_BNAD = "奔驰汽车";
        }
    
        string getBand()
        {
            return BENZ_BNAD;
        }
    };
    
    //奔驰商务车
    class BenzVan :public AbsBenz
    {
        string R_SEARIES;
    public:
        BenzVan():AbsBenz()
        {
            R_SEARIES = "R系列商务车";
        }
        string getModel()
        {
            return R_SEARIES;
        }
    };
    
    //奔驰Suv
    class BenzSuv :public AbsBenz
    {
        string G_SEARIES;
    public:
        BenzSuv():AbsBenz()
        {
            G_SEARIES = "G系列Suv";
        }
        string getModel()
        {
            return G_SEARIES;
        }
    };
    
    //抽象工厂
    class CarFactory
    {
    public:
        //生产SUV型
        virtual ICar* createSuv() = 0;
        //生产商务车型
        virtual ICar* createVan() = 0;
    };
    
    //宝马车工厂
    class BMWFactory : public CarFactory
    {
    public:
        ICar* createSuv()
        {
            return new BMWSuv();
        }
    
        ICar* createVan()
        {
            return new BMWVan();
        }
    };
    
    //奔驰车工厂
    class BenzFactory : public CarFactory
    {
    public:
        ICar* createSuv()
        {
            return new BenzSuv;
        }
    
        ICar* createVan()
        {
            return new BenzVan();
        }
    };
    
    int main()
    {
        //要求生产一辆奔驰车
        cout <<"===要求生产一辆奔驰车SUV===" << endl;
        //首先找奔驰车的工厂
        CarFactory* carFactory = new BenzFactory();
        //开始生产
        ICar* car = carFactory->createSuv();
        //生产完毕,展示一下车辆信息
        cout << "===车辆生产完毕,详细信息如下===" << endl;
        cout << "汽车品牌:" << car->getBand() <<endl;
        cout << "汽车型号:" << car->getModel() <<endl;
    
        return 0;
    };
    /*输出结果
     ===要求生产一辆奔驰车SUV===
    ===车辆生产完毕,详细信息如下===
    汽车品牌:奔驰汽车
    汽车型号:G系列Suv
    */

    26.2.2 建造者模式

    (1)整体:汽车。部分:引擎和车轮

    (2)Builder:BenzBuilder和BMWBuilder

    【编程实验】按建造者模式生产车辆

     

    //创建型模式大PK——抽象工厂方法和建造者模式
    //实例:利用建造者模式生产汽车
    #include <iostream>
    using namespace std;
    
    //**********************辅助类*******************************
    //生产蓝图(这个蓝图会交给Director,让他这个要求去生产汽车)
    class Blueprint
    {
    private:
        string wheel;   //车轮的要求
        string engine;  //引擎的要求
    public:
        string getWheel(){return wheel;}
        void setWheel(string value)
        {
            wheel = value;
        }
    
        string getEngine(){return engine;}
        void setEngine(string value)
        {
            engine = value;
        }
    };
    
    //车辆产品
    class ICar
    {
    public:
        //汽车车轮
       virtual string getWheel() = 0;
       //汽车引擎
       virtual string getEngine() = 0;
       //显示信号
       virtual string toString() = 0;
       virtual ~ICar (){}
    };
    
    //具体车辆
    class Car : public ICar
    {
    private:
        string engine;  //引擎
        string wheel;   //车轮
    public:
        Car(string engine, string wheel)
        {
            this->engine = engine;
            this->wheel = wheel;
        }
    
        string getEngine()
        {
            return engine;
        }
        string getWheel()
        {
            return wheel;
        }
    
        //演示车辆信息
        string toString()
        {
            return "车的轮子是:" + wheel + "
    车的引擎是:" + engine;
        }
    };
    
    //抽象建造者
    class CarBuilder
    {
    private:
        //ICar* car; //等建造的汽车
        Blueprint* bp; //设计蓝图
    protected:
        //只有具体的建造者才可以查看蓝图
        Blueprint* getBlueprint(){return bp;}
    public:
        //接收一份设计蓝图
        void setBlueprint(Blueprint* value)
        {
            bp = value;
        }
    
        //部件的构建
        virtual string buildWheel() = 0;
        virtual string buildEngine() = 0;
    
        //按照顺序生产一辆车
        Car* buildCar()
        {
            return  new Car(buildEngine(),buildWheel());
        }
        virtual ~CarBuilder(){}
    };
    
    //宝马车建造车间
    class BMWBuilder : public CarBuilder
    {
    public:
        string buildEngine()
        {
            //按车间主任(Director)手里的蓝图进行设计
            return getBlueprint()->getEngine();
        }
    
        string buildWheel()
        {
            //按车间主任(Director)手里的蓝图进行设计
            return getBlueprint()->getWheel();
        }
    };
    
    //奔驰车建造车间
    class BenzBuilder : public CarBuilder
    {
    public:
        string buildEngine()
        {
            //按车间主任(Director)手里的蓝图进行设计
            return getBlueprint()->getEngine();
        }
    
        string buildWheel()
        {
            //按车间主任(Director)手里的蓝图进行设计
            return getBlueprint()->getWheel();
        }
    };
    
    //导演类:Director
    class Director
    {
    private:
        //持有建造者的引用
        CarBuilder* bmwBuilder;
        CarBuilder* benzBuilder;
    public:
        Director()
        {
            bmwBuilder = new BMWBuilder();
            benzBuilder = new BMWBuilder();
        }
        //生产车辆
        ICar* createCar(CarBuilder* carBuilder, string engine, string wheel)
        {
            //导演手中的蓝图
            Blueprint bp;
            bp.setEngine(engine);
            bp.setWheel(wheel);
            carBuilder->setBlueprint(&bp);
            return carBuilder->buildCar();
        }
        //生产奔驰SUV
        ICar* createBenzSuv()
        {
            return createCar(benzBuilder, "benz的引擎","benz的轮胎");
        }
    
        //生产宝马商务
        ICar* createBMWVan()
        {
            return createCar(bmwBuilder, "BMW的引擎","BMW的轮胎");
        }
    
        //生产混合车型
         ICar* createComplexCar()
        {
            return createCar(bmwBuilder, "BMW的引擎","benz的轮胎");
        }
    
        ~Director()
        {
            delete benzBuilder;
            delete bmwBuilder;
        }
    };
    
    int main()
    {
        //定义一个导演类
        Director director;
        //生成一辆奔驰车SUV
        cout <<"===制造一辆奔驰SUV===" << endl;
        ICar* benzSuv = director.createBenzSuv();
        cout << benzSuv->toString() << endl;
    
        cout <<"===制造一辆宝马商务车===" << endl;
        ICar* bmwVan = director.createBMWVan();
        cout << bmwVan->toString() << endl;
    
        cout <<"===制造一辆混合车===" << endl;
        ICar* complexCar = director.createComplexCar();
        cout << complexCar->toString() << endl;
    
        delete benzSuv;
        delete bmwVan;
        delete complexCar;
    
        return 0;
    };
    /*输出结果
    ===制造一辆奔驰SUV===
    车的轮子是:benz的轮胎
    车的引擎是:benz的引擎
    ===制造一辆宝马商务车===
    车的轮子是:BMW的轮胎
    车的引擎是:BMW的引擎
    ===制造一辆混合车===
    车的轮子是:benz的轮胎
    车的引擎是:BMW的引擎
    */

    26.2.3 最佳实践

    (1)抽象工厂模式只关心一个工厂到底生产了哪些产品,不关心具体怎么生产的。

    (2)建造者模式要求按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新的产品

    (3)抽象工厂使用“工厂”来描述产品的构建,它是一种更高层次看对象的构建,而建造者使用“车间”来描述,不同的车间完成不同的创建和装配任务,一个完整的汽车生产过程需要引擎制造车间、引擎装配车间的配合才能完成,它们配合的基础是设计蓝图,而这个蓝图掌握在车间主任(Director)手中,它给建造者车间什么蓝图就能生产什么产品,它更关心建造过程。

    (4)相对来说,抽象工厂模式比建造者模式的尺度更大,它关注产品整体,而建造者模式关注的是构建过程

    (5)如果希望屏蔽对象的创建过程,只提供一个良好的封装,可以选择抽象工厂模式。如果在构件时通过不同的装配产生出新的对象,可以使用建造者模式。

  • 相关阅读:
    深入理解计算机系统(3.7)------过程(函数的调用原理)
    深入理解计算机系统(3.6)------汇编的流程控制
    深入理解计算机系统(3.5)------特殊的算术操作指令
    深入理解计算机系统(3.4)------算术和逻辑操作
    深入理解计算机系统(3.3)------操作数指示符和数据传送指令
    深入理解计算机系统(3.2)------程序编码以及数据格式
    redis调优 -- 内存碎片
    windows及linux环境下永久修改pip镜像源的方法
    Nginx限制某个IP同一时间段的访问次数和请求数示例代码
    Pycharm安装详细教程
  • 原文地址:https://www.cnblogs.com/5iedu/p/5655196.html
Copyright © 2020-2023  润新知