夏天/isummer

Sun of my life !Talk is cheap, Show me the code! 追风赶月莫停留,平芜尽处是春山~

博客园 首页 新随笔 联系 管理

23 DesignPatterns学习笔记:C++语言实现 --- 1.4 Builder

2016-07-21

(www.cnblogs.com/icmzn)


模式理解

 

1. Builder 模式定义:
    将一个复杂的对象的构建与他的表示分离,不同的构建过程可以创建不同的表示。
    要包含四个部分
    (1)抽象构建角色 : 构建过程抽象方法
    (2)具体构建角色 : 构建一种类型的对象
    (3)零部件角色 : 一般采用模板方法来确定所有零部件,
    (4)监管角色Director: 怎么来构建,监管来确定,采用组合的设计原则来封装不同的构建者
    关键是Director 角色完成不同零件的构建程序的协调,并直接向上层返回已经特定构造类型
2. Builder 模式优点
(1)封装性,上层模块不必知道内部构建过程细节。
(2)构建角色相互独立,并且容易扩展,这对程序非常有利。因为抽象构建角色已经定义好接口,很好扩展。
(3)因为构建角色是独立的,所以构建细节进行修改,对其他模块没有影响。

3.Builder 模式应用场景
(1)产品类非常复杂,并且产品类中的构建书序不同产生的对象不同。可以使用。

4.Builder 模式讨论
(1)Builder 模式与Abstract Factory模式相同点,都是创建大量不同类型的对象,
    他们的区别是Builder模式是按照不同类的对象的不同零件的构建顺序创建对象,并通过相同的创建过程来获得不同的对象,他们的不是直接返回的,而是由Director
角色维护创建;Abstract Factory模式对象是直接放回的,即根据创建复杂的抽象接口创建。
    其次,虽然二者都是创建类的,但是他们的注重点不同,Builder 模式注重零件的类型和构建过程顺序,而Abstract Factory注重产生对象。


 程序实现(C++)

 Builder.h

 1 #pragma once
 2 #ifndef _CBUILDER_H_
 3 #define _CBUILDER_H_
 4 #include "CarModel.h"
 5 //抽象构建者角色
 6 class CBuilder
 7 {
 8 public:
 9     CBuilder();
10     ~CBuilder();
11 public:
12     virtual void setBuilderOrders(const vector<CarBuilderOrder>& orders) = 0;
13     virtual CCarModel* getCarModel() = 0;
14     //(1)CCArModel 不能是纯虚函数,因为需要只用对象
15     //(2)因为父类对象不能直接转化为子类对象,但是可以使用指针向下转型,传递,所以返回父类的指针。
16     //即子类指针 可以直接复制给父类指针; 父类指针可以接受子类指针,多态行为。
17 };
18 
19 //具体构建者角色
20 class CBenzeCarBuilder : public CBuilder
21 {
22 public:
23     CBenzeCarBuilder()
24     {
25         m_pBenzeCar = new CBenzeCar();
26     }
27     ~CBenzeCarBuilder()
28     {
29         delete m_pBenzeCar;
30     }
31 public:
32     void setBuilderOrders(const vector<CarBuilderOrder>& orders) override
33     {
34         m_pBenzeCar->setSequence(orders);
35     }
36     //返回的是对象的副本 注意!!!
37     CCarModel* getCarModel() override
38     {
39         return m_pBenzeCar;
40     }
41 private:
42     CBenzeCar* m_pBenzeCar;
43 };
44 
45 //具体构建者角色
46 class CBMWCarBuilder : public CBuilder
47 {
48 public:
49     CBMWCarBuilder()
50     {
51         m_pBMWCar = new CBMWCar();
52     }
53     ~CBMWCarBuilder()
54     {
55         delete m_pBMWCar;
56     }
57 public:
58     void setBuilderOrders(const vector<CarBuilderOrder>& orders) override
59     {
60         m_pBMWCar->setSequence(orders);
61     }
62     //返回的是对象的副本 注意!!!
63     CCarModel* getCarModel() override
64     {
65         return m_pBMWCar;
66     }
67 private:
68     CBMWCar* m_pBMWCar;
69 };
70 
71 
72 #endif

Builder.cpp

 1 #include "Builder.h"
 2 
 3 
 4 CBuilder::CBuilder()
 5 {
 6 }
 7 
 8 
 9 CBuilder::~CBuilder()
10 {
11 }

CarModel.h

  1 #pragma once
  2 #ifndef _CCARMODEL_H_
  3 #define _CCARMODEL_H
  4 
  5 #include <vector>
  6 using namespace std;
  7 //模板方法模式 + 构建模式
  8 //带Hook Method 方法的模板方法模式
  9 enum CarBuilderOrder{eStart, eAlearm, eStop};
 10 #define OrderSize 3
 11 
 12 class CCarModel
 13 {
 14 public:
 15     CCarModel();
 16     ~CCarModel();
 17 //不对外公开
 18 protected:
 19     //不能用纯虚函数,因为需要根据父类复制对象
 20     virtual void start() = 0;
 21     virtual void alearm() = 0;
 22     virtual void stop() = 0;
 23     //Hook Method, 由子类决定模板的顺序情况
 24     virtual    bool isAlearm()
 25     {
 26         return true;
 27     }
 28 public :
 29     //对外公开的模板方法
 30     void setSequence(const vector<CarBuilderOrder>& sequence)
 31     {
 32         this->m_eOrders = sequence;
 33     }
 34     void run()
 35     {
 36         for (auto temp : m_eOrders)
 37         {
 38             switch (temp)
 39             {
 40             case eStart:
 41                 start();
 42                 break;
 43             case eAlearm:
 44                 alearm();
 45                 break;
 46             case eStop:
 47                 stop();
 48                 break;
 49             default:
 50                 throw "the constructor orders error !!!";
 51             }
 52         }
 53  
 54     }
 55 
 56 private:
 57     vector<CarBuilderOrder> m_eOrders;
 58 };
 59 
 60 //奔驰车在运行不需要警报声...
 61 class CBenzeCar : public CCarModel
 62 {
 63 public:
 64 
 65 protected:
 66     void start() override;
 67     void alearm() override;
 68     void stop() override;
 69     bool isAlearm() override
 70     {
 71         return false;
 72     }
 73 
 74 };
 75 
 76 class CBMWCar : public CCarModel
 77 {
 78 public:
 79     CBMWCar()
 80     {
 81         //默认是打开
 82         m_bAlearm = true;
 83     }
 84     void setAlearm(bool flag)
 85     {
 86         m_bAlearm = flag;
 87     }
 88     //不对外公开的方法
 89 protected:
 90     void start() override;
 91     void alearm() override;
 92     void stop() override;
 93     bool isAlearm()
 94     {
 95         return m_bAlearm;
 96     }
 97     //提供友好的接口形式
 98 private:
 99     bool m_bAlearm;
100 };
101 
102 #endif

CarMode.cpp

 

 1 #include "CarModel.h"
 2 #include <iostream>
 3 using namespace std;
 4 
 5 CCarModel::CCarModel()
 6 {
 7     m_eOrders.reserve(OrderSize);
 8 }
 9 
10 
11 CCarModel::~CCarModel()
12 {
13 }
14 
15 //CBenzeCar
16 void CBenzeCar::alearm()
17 {
18     cout << "CBenzeCar alearm ... " << endl;
19 }
20 void CBenzeCar::start()
21 {
22     cout << "CBenzeCar start ... " << endl;
23 }
24 void CBenzeCar::stop()
25 {
26     cout << "CBenzeCar stop ... " << endl;
27 }
28 
29 
30 //CBenzeCar
31 void CBMWCar::alearm()
32 {
33     cout << "CBMWCar alearm ... " << endl;
34 }
35 void CBMWCar::start()
36 {
37     cout << "CBMWCar start ... " << endl;
38 }
39 void CBMWCar::stop()
40 {
41     cout << "CBMWCar stop ... " << endl;
42 }

Decorator.h

 1 #pragma once
 2 #ifndef _CDIRECTER_H_
 3 #define _CDIRECTER_H_
 4 #include "Builder.h"
 5 
 6 //监管者角色,采用组合的方式
 7 class CDirecter
 8 {
 9 public:
10     CDirecter();
11     ~CDirecter();
12 private:
13     CBMWCarBuilder* m_pBMWBuilder;
14     CBenzeCarBuilder* m_pBenzeBuilder;
15     vector<CarBuilderOrder> m_eOrders;
16 public:
17     //监管者角色分别构建不同类型的对象,与模板方法相结合
18     CBenzeCar getBenzeCarA()
19     {
20         //正常汽车
21         m_eOrders.clear();
22         m_eOrders.push_back(eStart);
23         m_eOrders.push_back(eAlearm);
24         m_eOrders.push_back(eStop);
25 
26         //设置构建顺序
27         m_pBenzeBuilder->setBuilderOrders(m_eOrders);
28         //父类转化为子类
29         //采用传递对象副本的方式,能与创建新的对象。
30         return *(static_cast<CBenzeCar*>(m_pBenzeBuilder->getCarModel()));
31     }
32     CBenzeCar getBenzeCarB()
33     {
34         //反常汽车
35         m_eOrders.clear();
36         m_eOrders.push_back(eStop);
37         m_eOrders.push_back(eAlearm);
38         m_eOrders.push_back(eStart);
39         //设置构建顺序
40         m_pBenzeBuilder->setBuilderOrders(m_eOrders);
41         //父类转化为子类
42         //采用传递对象副本的方式,能与创建新的对象。
43         return *(static_cast<CBenzeCar*>(m_pBenzeBuilder->getCarModel()));
44 
45     }
46     CBMWCar getBMWCarA()
47     {
48         //正常汽车
49         m_eOrders.clear();
50         m_eOrders.push_back(eStart);
51         m_eOrders.push_back(eAlearm);
52         m_eOrders.push_back(eStop);
53 
54         //设置构建顺序
55         m_pBMWBuilder->setBuilderOrders(m_eOrders);
56         //父类转化为子类
57         //采用传递对象副本的方式,能与创建新的对象。
58         return *(static_cast<CBMWCar*>(m_pBMWBuilder->getCarModel()));
59     }
60     CBMWCar getBMWCarB()
61     {
62         //反常汽车
63         m_eOrders.clear();
64         m_eOrders.push_back(eStop);
65         m_eOrders.push_back(eAlearm);
66         m_eOrders.push_back(eStart);
67         //设置构建顺序
68         m_pBMWBuilder->setBuilderOrders(m_eOrders);
69         //父类转化为子类
70         //采用传递对象副本的方式,能与创建新的对象。
71         return *(static_cast<CBMWCar*>(m_pBMWBuilder->getCarModel()));
72     }
73 };
74 
75 #endif 

Decorator.cpp

 1 #include "Directer.h"
 2 
 3 
 4 CDirecter::CDirecter()
 5 {
 6     m_pBenzeBuilder = new CBenzeCarBuilder();
 7     m_pBMWBuilder = new CBMWCarBuilder();
 8     m_eOrders.reserve(OrderSize);
 9 }
10 
11 
12 CDirecter::~CDirecter()
13 {
14 }

 


(1)模板应用

main.cpp

 

 1 // 04Builder.cpp : 定义控制台应用程序的入口点。
 2 //
 3 
 4 #include "stdafx.h"
 5 #include "Directer.h"
 6 #include <iostream>
 7 using namespace std;
 8 
 9 int _tmain(int argc, _TCHAR* argv[])
10 {
11     CDirecter* director = new CDirecter();
12     cout << "BenzeCarA-------------" << endl;
13     for (int i = 0; i < 5; i++)
14     {
15         director->getBenzeCarA().run();
16     }
17     
18     cout << "BenzeCarB-------------" << endl;
19     for (int i = 0; i < 5; i++)
20     {
21         director->getBenzeCarB().run();
22     }
23 
24     cout << "BMWCarA-------------" << endl;
25     for (int i = 0; i < 5; i++)
26     {
27         director->getBMWCarA().run();
28     }
29 
30     cout << "BMWCarB-------------" << endl;
31     for (int i = 0; i < 5; i++)
32     {
33         director->getBMWCarB().run();
34     }
35 
36     system("pause");
37     return 0;
38 }

 

 

 

(2)输出展示

             

 

posted on 2016-07-21 22:51  夏天/isummer  阅读(203)  评论(0编辑  收藏  举报