zoukankan      html  css  js  c++  java
  • 生成器模式(Builder)C++实现

    意图:将一个复杂对象的创建与它的表示分离,使得同样的构建过程可以创建不同的表示。

    适用性:1.当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。

        2.当构建过程必须允许被构建的对象有不同的表示时。

    效果:   1.使得可以改变一个产品的内部表示。

        2.隐藏产品的内部结构。

        3.使得构造代码和表示代码分离。

        4.使得可以对构建过程进行更精确的控制。

    代码实例:

    代码以构建Room为实例,而Room由四个Site组成,Site可以是Wall、Window、Door、Grass、Wood。(其中

    wood和grass分别表示木制墙和玻璃墙). 这里Room可以有3 Wall  1 Door 或 2 wall 1 Door 1 Window等各种

    表示。构建在具体Builder中实现,而在Director中表示,体现了效果3.

    在Builder头文件下,首先我们创建各种要用到的类:

     1 #ifndef _BUILDER_
     2 #define _BUILDER_
     3 #include <string>
     4 #include <iostream>
     5 using namespace std;
     6 const int MAXSITE = 4;
     7 
     8 class Site{
     9 public:
    10     Site(string str):_mName(str){}
    11     string _mName;
    12 };
    13 
    14 class Wall:public Site{
    15 public:
    16     Wall():Site("wall"){}
    17 };
    18 
    19 class Wood:public Site{
    20 public:
    21     Wood():Site("wood"){}
    22 };
    23 
    24 class Grass:public Site{
    25 public:
    26     Grass():Site("grass"){}
    27 };
    28 
    29 class Door:public Site{
    30 public:
    31     Door():Site("door"){}
    32 };
    33 
    34 class Window:public Site{
    35 public:
    36     Window():Site("window"){}
    37 };
    38 
    39 class Room{
    40 public:
    41     Room(){    
    42         for(int i = 0; i < MAXSITE; i++)
    43             _mSite[i] = NULL;
    44     }
    45     void Printf()
    46     {
    47         for(int i = 0; i < MAXSITE; i++)
    48         {
    49             if(_mSite[i] != NULL)
    50             cout<<_mSite[i]->_mName<<endl;
    51         }
    52     }
    53     Site* _mSite[MAXSITE];
    54 };
    要用到的类

    接着我们创建AbsBuilder,这里提供给向导器一个构造产品的抽象接口。因为不知道具体哪个类被创建并用于组成目标类,所以达到了效果2.

    class AbsBuilder{
    public:
    AbsBuilder(){}
    
    virtual void BuilderWall(){}
    virtual void BuilderDoor(){}
    virtual void BuilderWindow(){}
    virtual void BuilderGrass(){}
    virtual void BuilderWood(){}
    
    virtual Room* GetRoom() = 0;
    };

    然后是具体创建BuilderA/B...,体现了可以改变产品的内部表示(效果1.)

    class BuilderA:public AbsBuilder{
    
    public:
        BuilderA():_mNum(0){_mpRoom = new Room; }
    
        virtual void BuilderWall(){_mpRoom->_mSite[_mNum++] = new Wall;}
        virtual void BuilderDoor(){_mpRoom->_mSite[_mNum++] = new Door;}
        virtual void BuilderWindow()
        {
            _mpRoom->_mSite[_mNum++] = new Window;
            _mpRoom->_mSite[_mNum++] = new Window;
        }
    
        virtual Room* GetRoom(){return _mpRoom; }
    private:
        Room* _mpRoom;
        int _mNum;
    };
    
    class BuilderB:public AbsBuilder{
    
    public:
        BuilderB():_mNum(0){_mpRoom = new Room; }
        virtual void BuilderWood(){_mpRoom->_mSite[_mNum++] = new Wood;}
        virtual void BuilderDoor(){_mpRoom->_mSite[_mNum++] = new Door;}
        virtual void BuilderWindow()
        {
            _mpRoom->_mSite[_mNum++] = new Grass;
            _mpRoom->_mSite[_mNum++] = new Grass;
        }
    
        virtual Room* GetRoom(){return _mpRoom; }
    private:
        Room* _mpRoom;
        int _mNum;
    };
    
    #endif
    BuilderA/B

    在Director头文件下,创建类Director. 因为这里一步步构造产品,体现了效果4.

    class Director{
    public:
        Director(AbsBuilder* builder){_mBuilder = builder;}
        void construct()
        {
            _mBuilder->BuilderDoor();
            _mBuilder->BuilderWall();
            _mBuilder->BuilderWindow();
            _mBuilder->BuilderGrass();
            _mBuilder->BuilderWood();
        }
    private:
        AbsBuilder* _mBuilder;
    };

    main函数中:

    #include <iostream>
    using namespace std;
    
    #include "Builder.h"
    #include "Director.h"
    
    int main()
    {
        BuilderA* pBuilderA = new BuilderA;
        Director directro(pBuilderA);
        directro.construct();
        Room* roomA = pBuilderA->GetRoom();
        roomA->Printf();
    
        cout<<endl;
    
        BuilderB* pBuilderB = new BuilderB;
        Director directroB(pBuilderB);
        directroB.construct();
        Room* roomB = pBuilderB->GetRoom();
        roomB->Printf();
    
        cout<<endl;
        return 0;
    }
  • 相关阅读:
    主效应|处理误差 |组间误差|处理效应|随机误差|组内误差|误差|效应分析|方差齐性检验|SSE|SSA|SST|MSE|MSA|F检验|关系系数|完全随机化设计|区组设计|析因分析
    第二类错误|检验统计量|左偏|右偏|P值
    估计量|估计值|置信度|置信水平|非正态的小样本|t分布|大样本抽样分布|总体方差|
    参数|统计量|抽样分布|估计标准误差|标准误差|标准误|标准差|二项分布|泊松分布|中心极限定理|样本方差|
    ruby 分析日志,提取特定记录
    find 找出大文件
    momentjs 求小时差异
    linux下对date和timestamp的互转
    golang protobuf SetExtension
    对文本中的某两列求和,请统计重复出现次数
  • 原文地址:https://www.cnblogs.com/wrbxdj/p/4165011.html
Copyright © 2011-2022 走看看