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)输出展示