Buider模式
在软件设计中,有时候需要创建一个非常复杂的类对象,一次性的完成这个任务是非常艰巨的。但是,这个复杂的类对象通常可以分为几个较小的部分,这样,就可以分别创建这几个子对象然后组合为这个复杂类对象,这个过程相对来说比较稳定。但是,子对象的创建过程各不相同且可能产生变化。因此,根据OCP(Open-Closed Principle)原则,也需要对子对象的创建过程进行封装。
思路:定义一个抽象的创建者(Builder),这个抽象类规定了所有的具体创建者应该具有的功能---即如何创建复杂对象的特定的部分(子对象),创建过程由具体创建者实现。然后还需要定义一个指导者(Deirector),它知道如何使用Builder来创建复杂的对象。这时候客户(Client)只需要给指导者指定一个具体的Builder,就能够使用Builder来创建复杂的类对象了。至于创建细节,是指导者和客户不需要关心的。
场景描述:一个人想买电脑,首先他得先确定哪个牌子的,然后选定牌子之后,他就要去找牌子的经销商(Director),经销商监督这个牌子的厂家(Builder)一步步的完成电脑的装配工作的,具体的装配工作是这个人和经销商不需要关心的。
实现:
1、将变化的部分抽象成一个基类(Builder)和对应的接口函数。不会变化的时创建各个子对象的动作,变化的则是创建子对象的过程。因此抽象出来的基类是Builder,借口函数是BuilderPartA、BuilderPartB、BuilderPartC...
2、指导者如何使用创建者?将创建者基类的指针作为Director的成员,则指导者就能通过成员函数操作创建者了。
3、聚合,通过Director类中的contact函数,将各个子对象聚合起来,这里使用了多态,即基类的指针可以指向派生类对象。
具体实现:
1 /*Builder.h*/ 2 3 #ifndef BUILDER_H_INCLUDED 4 #define BUILDER_H_INCLUDED 5 6 class Builder 7 { 8 public: 9 virtual ~Builder(){}; 10 Builder(){}; 11 12 //创建子对象的功能,声明为接口 13 virtual void BuilderPartA() = 0; 14 virtual void BuilderPartB() = 0; 15 }; 16 17 class BuilderA:public Builder 18 { 19 public: 20 ~BuilderA(){}; 21 BuilderA(){}; 22 virtual void BuilderPartA() 23 { 24 std::cout<<"BuilderA build PartA"<<std::endl; 25 } 26 virtual void BuilderPartB() 27 { 28 std::cout<<"BuilderA build PartB"<<std::endl; 29 } 30 }; 31 32 class BuilderB:public Builder 33 { 34 public: 35 ~BuilderB(){}; 36 BuilderB(){}; 37 virtual void BuilderPartA() 38 { 39 std::cout<<"BuilderB build PartA"<<std::endl; 40 } 41 virtual void BuilderPartB() 42 { 43 std::cout<<"BuilderB build PartB"<<std::endl; 44 } 45 }; 46 #endif // BUILDER_H_INCLUDED 47 48 /*Director.h*/ 49 50 #ifndef DIRECTOR_H_INCLUDED 51 #define DIRECTOR_H_INCLUDED 52 53 class Director 54 { 55 public: 56 ~Director(){}; 57 //Director(Builder* m_pBuilder1, Builder* m_pBuilder2 = NULL):pBuilder1(m_pBuilder1),pBuilder2(m_pBuilder2){}; 58 Director(Builder* m_pBuilder):pBuilder(m_pBuilder){}; 59 void contact(); 60 private: 61 Builder* pBuilder; 62 //Builder* pBuilder1; 63 //Builder* pBuilder2; 64 }; 65 66 void Director::contact() 67 { 68 pBuilder->BuilderPartA(); 69 pBuilder->BuilderPartB(); 70 //pBuilder1->BuilderPartA(); 71 //pBuilder2->BuilderPartB(); 72 } 73 74 #endif // DIRECTOR_H_INCLUDED 75 76 77 /*测试程序*/ 78 #include<iostream> 79 #include"Builder.h" 80 #include"Director.h" 81 using namespace std; 82 int main() 83 { 84 BuilderA* pBuilderA = new BuilderA(); 85 Director* pDirector = new Director(pBuilderA); 86 pDirector->contact(); 87 BuilderB* pBuilderB = new BuilderB(); 88 Director* pDirector_1 = new Director(pBuilderB); 89 pDirector_1->contact(); 90 //Director* pDirector_2 = new Director(pBuilderA, pBuilderB); 91 //pDirector_2->contact(); 92 delete pBuilderA, pBuilderB; 93 delete pDirector, pDirector_1; 94 return 0; 95 }