生成器模式的主要思想:将产品对象的创建与表现分离开,并且同样的创建过程可以有不同的产品表现。
直白一点可以理解为:待创建的对象是复杂的,一般情况下是需要经过多个步骤的创建后,最终才能将完整产品创建好,而且每个步骤所创建的都只是产品的一部分而已。这一切的创建步骤,由统一的执导者来完成,称之为:Director(即:导演)。而产品以及组成产品的各个部分的生成细节,由生成器(或者称之为创建者、构建者也行)来完成,称之为:Builder。因此,类关系图参考如下:
由图可知,对Client来说,同样的执导者,是可以生成不同的产品的,并且最重要的是这一切的构建过程,对它来说是完全透明的,其实它也完全不关心(也不需要关心)产品是如何创建出来的,他只要结果(即:产品)。因此,Client想要什么样的产品,只需要使用相应的生成器去构建即可,仅此而已。
关于该模式的协作图参考如下:
由协作图可清晰看出Client、Director、Builder之前的协作关系。模式的编码结构参考如下:
1 namespace builder 2 { 3 // -------- 产品 -------- 4 class Product1 {}; 5 class Product2 {}; 6 7 // -------- 生成器 -------- 8 class Builder 9 { 10 public: 11 virtual void buildPartA() { /*some code here........*/ } 12 virtual void buildPartB() { /*some code here........*/ } 13 virtual void buildPartC() { /*some code here........*/ } 14 // ........ 15 virtual void buildPartN() { /*some code here........*/ } 16 17 };//class Builder 18 class ConcreteBuilder1 : public Builder 19 { 20 public: 21 virtual void buildPartA() { /*some code here........*/ } 22 virtual void buildPartC() { /*some code here........*/ } 23 virtual void buildPartE() { /*some code here........*/ } 24 // ........ 25 26 Product1* getProduct1() { return m_pProduct1; } 27 28 private: 29 Product1* m_pProduct1; 30 31 };//class ConcreteBuilder1 32 class ConcreteBuilder2 : public Builder 33 { 34 public: 35 virtual void buildPartB() { /*some code here........*/ } 36 virtual void buildPartC() { /*some code here........*/ } 37 virtual void buildPartD() { /*some code here........*/ } 38 // ........ 39 40 Product2* getProduct1() { return m_pProduct2; } 41 42 private: 43 Product2* m_pProduct2; 44 45 };//class ConcreteBuilder2 46 47 // -------- 导演 -------- 48 class Director 49 { 50 public: 51 void construct() { 52 auto pBuilder = this->getBuilder(); 53 if (nullptr == pBuilder) { 54 return; 55 } 56 pBuilder->buildPartA(); 57 pBuilder->buildPartB(); 58 pBuilder->buildPartC(); 59 // ........ 60 pBuilder->buildPartN(); 61 } 62 63 void setBuilder(Builder* pBuilder) { m_pBuilder = pBuilder; } 64 65 private: 66 Builder* getBuilder() { return m_pBuilder; } 67 68 private: 69 Builder* m_pBuilder; 70 71 };//class Director 72 73 // -------- 客户 -------- 74 class Client 75 { 76 public: 77 void test() { 78 auto pBuilder = new (std::nothrow) ConcreteBuilder1(); 79 auto pDirector = new (std::nothrow) Director(); 80 if (nullptr == pBuilder || nullptr == pDirector) { 81 // some code like below. 82 //SAFE_DELETE(pBuilder); 83 //SAFE_DELETE(pDirector); 84 return; 85 } 86 pDirector->setBuilder(pBuilder); 87 pDirector->construct(); 88 auto pMyProduct = pBuilder->getProduct1(); 89 // some other code here........ 90 } 91 92 };//class Client 93 94 }//namespace builder