• 创建型模式のBuilder建造者模式


    建造者模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。一段晦涩难懂的文字,实现创建不同表示的方法就是给创建的过程传入创建的参数。详细的还是看代码吧。

    10.1.解释

    main(),客户

    CCarModel,产品模型

    CBenzModel,奔驰模型

    CBMWModel,宝马模型

    ICarBuilder,建造者接口

    CBenzBuilder,奔驰建造者

    CBMWBuilder,宝马建造者

    CDirector,导演

    说明:CCarModel实现模板方法,Builder负责开始建造产品。建造产品时,构建的顺序由Director或main决定。

    注意:建造者模式和抽象工厂非常类似。建造者更重视产品建造时的逻辑顺序,而抽象工厂更重视生产出不同型号的产品,抽象工厂不关心顺序。

    看代码:

     1 // Builder.cpp
     2 #include "stdafx.h"
     3 #include "CarModel.h"
     4 #include "BenzModel.h"
     5 #include "BMWModel.h"
     6 #include "BenzBuilder.h"
     7 #include "BMWBuilder.h"
     8 #include "Director.h"
     9 #include <vector>
    10 #include <iostream>
    11 using std::vector;
    12 using std::string;
    13 using std::cout;
    14 using std::endl;
    15 
    16 
    17 void DoBenzRun()  //没有使用模式时,需要把步骤一条一条的传入模型。
    18 {
    19     cout << "----------生成奔驰模型----------" << endl;
    20     CBenzModel *pBenz = new CBenzModel();
    21     vector<string> seq;
    22     seq.push_back("engine boom");//客户要求run的时候先发动引擎
    23     seq.push_back("start");//启动起来
    24     seq.push_back("stop");//开了一段就停下来
    25 
    26     pBenz->SetSequence(&seq);
    27     pBenz->Run();
    28     delete pBenz;
    29 }
    30 
    31 
    32 void DoBuilder()    //使用模式后,由benzBuilder和bmwBuilder来生成,并且使用同样的创建顺序。
    33 {
    34     cout << "----------用同一个顺序,生成模型----------" << endl;
    35     vector<string> seq;
    36     seq.push_back("engine boom");
    37     seq.push_back("start");
    38     seq.push_back("stop");
    39 
    40     CBenzBuilder benzBuilder;
    41     benzBuilder.SetSequence(&seq);
    42     CBenzModel *pBenz = dynamic_cast<CBenzModel*>(benzBuilder.GetCarModel());
    43     pBenz->Run();
    44 
    45     CBMWBuilder bmwBuilder;
    46     bmwBuilder.SetSequence(&seq);
    47     CBMWModel *pBmw = dynamic_cast<CBMWModel*>(bmwBuilder.GetCarModel());
    48     pBenz->Run();
    49 }
    50 void DoDirector()    //使用指导者来封装创建的逻辑,把创建的顺序内聚在指导者类里面。
    51 {
    52     cout << "----------批量生成模型----------" << endl;
    53     CDirector director;
    54 
    55     //1W辆A类型的奔驰车
    56     for(int i = 0; i < 2; i++)
    57         director.GetABenzModel()->Run();
    58 
    59     //100W辆B类型的奔驰车
    60     for(int i = 0; i < 2; i++)
    61         director.GetBBenzModel()->Run();
    62 
    63     //1000W辆C类型的宝马车
    64     for(int i = 0; i < 2; i++)
    65         director.GetCBMWModel()->Run();
    66 }
    67 int _tmain(int argc, _TCHAR* argv[])
    68 {
    69     DoBenzRun();
    70 
    71     DoBuilder();
    72 
    73     DoDirector();
    74 
    75     _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
    76     _CrtDumpMemoryLeaks();
    77     return 0;
    78 }
     1 //CarModel.h
     2 
     3 #pragma once
     4 #include <vector>
     5 #include <iostream>
     6 using std::vector;
     7 using std::string;
     8 class CCarModel
     9 {
    10 public:
    11     CCarModel(void);
    12     virtual ~CCarModel(void);
    13     void Run();
    14     void SetSequence(vector<string> *pSeq);
    15 protected:
    16     virtual void Start() = 0;
    17     virtual void Stop() = 0;
    18     virtual void Alarm() = 0;
    19     virtual void EngineBoom() = 0;
    20 private:
    21     vector<string> * m_pSequence;
    22 };
     1 //CarModel.cpp
     2 
     3 #include "StdAfx.h"
     4 #include "CarModel.h"
     5 #include <vector>
     6 #include <iostream>
     7 using std::vector;
     8 using std::string;
     9 CCarModel::CCarModel(void)
    10 {
    11 }
    12 CCarModel::~CCarModel(void)
    13 {
    14 }
    15 void CCarModel::SetSequence(vector<string> *pSeq)
    16 {
    17     m_pSequence = pSeq;
    18 }
    19 void CCarModel::Run()
    20 {
    21     vector<string>::const_iterator it = m_pSequence->begin();
    22     for (; it < m_pSequence->end(); ++it)
    23     {
    24         string actionName = *it;
    25         if(actionName.compare("start") == 0)
    26         {
    27             Start();
    28         }
    29         else if(actionName.compare("stop") == 0)
    30         {
    31             Stop();
    32         }
    33         else if(actionName.compare("alarm") == 0)
    34         {
    35             Alarm();
    36         }
    37         else if(actionName.compare("engine boom") == 0)
    38         {
    39             EngineBoom();
    40         }
    41     }
    42 }
     1 //BenzModel.h
     2 
     3 #pragma once
     4 #include "carmodel.h"
     5 class CBenzModel :
     6     public CCarModel
     7 {
     8 public:
     9     CBenzModel(void);
    10     ~CBenzModel(void);
    11 protected:
    12     void Start();
    13     void Stop();
    14     void Alarm();
    15     void EngineBoom();
    16 };
    17 
    18 //BenzModel.cpp
    19 
    20 #include "StdAfx.h"
    21 #include "BenzModel.h"
    22 #include <iostream>
    23 using std::cout;
    24 using std::endl;
    25 CBenzModel::CBenzModel(void)
    26 {
    27 }
    28 CBenzModel::~CBenzModel(void)
    29 {
    30 }
    31 void CBenzModel::Start()
    32 {
    33     cout << "奔驰发动..." << endl;
    34 }
    35 void CBenzModel::Stop()
    36 {
    37     cout << "奔驰停车..." << endl;
    38 }
    39 void CBenzModel::Alarm()
    40 {
    41     cout << "奔驰鸣笛" << endl;
    42 }
    43 void CBenzModel::EngineBoom()
    44 {
    45     cout << "奔驰引擎声音是这样...." << endl;
    46 }
    47 
    48 //BMWModel.h
    49 
    50 #pragma once
    51 #include "carmodel.h"
    52 class CBMWModel :
    53     public CCarModel
    54 {
    55 public:
    56     CBMWModel(void);
    57     ~CBMWModel(void);
    58 protected:
    59     void Start();
    60     void Stop();
    61     void Alarm();
    62     void EngineBoom();
    63 };
    64 
    65 //BMWModel.cpp
    66 
    67 #include "StdAfx.h"
    68 #include "BMWModel.h"
    69 #include <iostream>
    70 using std::cout;
    71 using std::endl;
    72 CBMWModel::CBMWModel(void)
    73 {
    74 }
    75 CBMWModel::~CBMWModel(void)
    76 {
    77 }
    78 void CBMWModel::Start()
    79 {
    80     cout << "宝马发动..." << endl;
    81 }
    82 void CBMWModel::Stop()
    83 {
    84     cout << "宝马停车..." << endl;
    85 }
    86 void CBMWModel::Alarm()
    87 {
    88     cout << "宝马鸣笛" << endl;
    89 }
    90 void CBMWModel::EngineBoom()
    91 {
    92     cout << "宝马引擎声音是这样...." << endl;
    93 }
     1 //ICarBuilder.h
     2 
     3 #pragma once
     4 #include "CarModel.h"
     5 #include <iostream>
     6 #include <vector>
     7 using std::string;
     8 using std::vector;
     9 class ICarBuilder
    10 {
    11 public:
    12     ICarBuilder(void)
    13     {
    14     }
    15     virtual ~ICarBuilder(void)
    16     {
    17     }
    18     virtual void SetSequence(vector<string> *pseq) = 0;
    19     virtual CCarModel * GetCarModel() = 0;
    20 };
     1 //BenzBuilder.h
     2 
     3 #pragma once
     4 #include "icarbuilder.h"
     5 #include "CarModel.h"
     6 #include <iostream>
     7 #include <vector>
     8 using std::string;
     9 using std::vector;
    10 class CBenzBuilder :
    11     public ICarBuilder
    12 {
    13 public:
    14     CBenzBuilder(void);
    15     ~CBenzBuilder(void);
    16     void SetSequence(vector<string> *pSeq);
    17     CCarModel * GetCarModel();
    18 private:
    19     CCarModel *m_pBenz;
    20 };
    21 //BenzBuilder.cpp
    22 
    23 #include "StdAfx.h"
    24 #include "BenzBuilder.h"
    25 #include "BenzModel.h"
    26 CBenzBuilder::CBenzBuilder(void)
    27 {
    28     m_pBenz = new CBenzModel();
    29 }
    30 CBenzBuilder::~CBenzBuilder(void)
    31 {
    32     delete m_pBenz;
    33 }
    34 void CBenzBuilder::SetSequence(vector<string> *pSeq)
    35 {
    36     m_pBenz->SetSequence(pSeq);
    37 }
    38 CCarModel * CBenzBuilder::GetCarModel()
    39 {
    40     return m_pBenz;
    41 }
     1 //BMWBuilder.h
     2 
     3 #pragma once
     4 #include "icarbuilder.h"
     5 #include "CarModel.h"
     6 #include <iostream>
     7 #include <vector>
     8 using std::string;
     9 using std::vector;
    10 class CBMWBuilder :
    11     public ICarBuilder
    12 {
    13 public:
    14     CBMWBuilder(void);
    15     ~CBMWBuilder(void);
    16     void SetSequence(vector<string> *pSeq);
    17     CCarModel * GetCarModel();
    18 private:
    19     CCarModel *m_pBMW;
    20 };
    21 
    22 //BMWBuilder.cpp
    23 
    24 #include "StdAfx.h"
    25 #include "BMWBuilder.h"
    26 #include "BMWModel.h"
    27 CBMWBuilder::CBMWBuilder(void)
    28 {
    29     m_pBMW = new CBMWModel();
    30 }
    31 CBMWBuilder::~CBMWBuilder(void)
    32 {
    33     delete m_pBMW;
    34 }
    35 void CBMWBuilder::SetSequence( vector<string> *pSeq )
    36 {
    37     m_pBMW->SetSequence(pSeq);
    38 }
    39 CCarModel * CBMWBuilder::GetCarModel()
    40 {
    41     return m_pBMW;
    42 }
     1 //Director.h
     2 
     3 #pragma once
     4 #include "BenzModel.h"
     5 #include "BMWModel.h"
     6 #include "BenzBuilder.h"
     7 #include "BMWBuilder.h"
     8 #include <vector>
     9 using std::vector;
    10 class CDirector
    11 {
    12 public:
    13     CDirector(void);
    14     ~CDirector(void);
    15     CBenzModel * GetABenzModel();
    16     CBenzModel * GetBBenzModel();
    17     CBMWModel * GetCBMWModel();
    18     CBMWModel * GetDBMWModel();
    19 private:
    20     vector<string> * m_pSeqence;
    21     CBenzBuilder * m_pBenzBuilder;
    22     CBMWBuilder * m_pBMWBuilder;
    23 };
    24 
    25 //Director.cpp
    26 
    27 #include "StdAfx.h"
    28 #include "Director.h"
    29 CDirector::CDirector(void)
    30 {
    31     m_pBenzBuilder = new CBenzBuilder();
    32     m_pBMWBuilder = new CBMWBuilder();
    33     m_pSeqence = new vector<string>();
    34 }
    35 CDirector::~CDirector(void)
    36 {
    37     delete m_pBenzBuilder;
    38     delete m_pBMWBuilder;
    39     delete m_pSeqence;
    40 }
    41 CBenzModel * CDirector::GetABenzModel()
    42 {
    43     m_pSeqence->clear();
    44     m_pSeqence->push_back("start");
    45     m_pSeqence->push_back("stop");
    46     m_pBenzBuilder->SetSequence(m_pSeqence);
    47     return dynamic_cast<CBenzModel*>(m_pBenzBuilder->GetCarModel());
    48 }
    49 CBenzModel * CDirector::GetBBenzModel()
    50 {
    51     m_pSeqence->clear();
    52     m_pSeqence->push_back("engine boom");
    53     m_pSeqence->push_back("start");
    54     m_pSeqence->push_back("stop");
    55     m_pBenzBuilder->SetSequence(m_pSeqence);
    56     return dynamic_cast<CBenzModel*>(m_pBenzBuilder->GetCarModel());
    57 }
    58 CBMWModel * CDirector::GetCBMWModel()
    59 {
    60     m_pSeqence->clear();
    61     m_pSeqence->push_back("alarm");
    62     m_pSeqence->push_back("start");
    63     m_pSeqence->push_back("stop");
    64     m_pBMWBuilder->SetSequence(m_pSeqence);
    65     return static_cast<CBMWModel*>(m_pBMWBuilder->GetCarModel());
    66 }
    67 CBMWModel * CDirector::GetDBMWModel()
    68 {
    69     m_pSeqence->clear();
    70     m_pSeqence->push_back("start");
    71     m_pBenzBuilder->SetSequence(m_pSeqence);
    72     return dynamic_cast<CBMWModel*>(m_pBMWBuilder->GetCarModel());
    73 }

    建造者模式属于创建型模式,主要关注创建的顺序,不同的顺序,生产的产品略有不同。

    本文转自:~~~

  • 相关阅读:
    Go 交叉编译
    go module 基本使用
    win10中安装Linux子系统
    VsCode/Pycharm配合python env 使用
    python virtualenv 基本使用
    Django 知识点小记
    Django中一种常见的setting与账密保存/读取方式
    win安装python模块出现依赖问题的解决方法 & No module named 'MySqldb'
    MySQL数据库文件
    如何在MySQL中分配innodb_buffer_pool_size
  • 原文地址:https://www.cnblogs.com/labi/p/3596095.html
Copyright © 2020-2023  润新知