生成器
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
封装一个产品的构造过程,并允许按步骤构造。
适用性
- 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
- 当构建过程必须允许被构造的对象有不同的表示时。
示例情境
每个客人的度假计划都不一样,比如天数、活动类型。希望提供一种方式来创建这个复杂的结构,而不会和创建它的步骤混在一起。
结构
Builder - 为创建一个Product对象的各个部件指定抽象接口。
ConcreteBuilder - 实现Builder的接口以构造和装配该产品的各个部件。定义并明确它所创建的表示。提供一个检索产品的接口。
Director - 构造一个使用Builder接口的对象。
Product - 表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程。包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
协作:
客户创建Director对象,并用它所想要的Builder对象进行配置。
一旦产品部件被生成,导向器就会通知生成器。
生成器处理导向器的请求,并将部件添加到该产品中。
客户从生成器中检索产品。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
| #include <iostream>
class Product { public: void display() { std::cout<<"Product: "<<m_part1<<","<<m_part2<<","<<m_part3<<std::endl; } public: int m_part1; int m_part2; int m_part3; };
class Builder { public: virtual void build_part(){} virtual void build_part1(int part1) {} virtual void build_part2(int part2) {} virtual void build_part3(int part3) {} virtual Product* get_result(){return NULL;} };
class ConcreteBuilderA : public Builder { public: ConcreteBuilderA(): Builder(), m_product(NULL) {} virtual void build_part() { if (!m_product) { m_product = new Product(); } } virtual Product* get_result() { return m_product; } void build_part1(int part1) { if (!m_product) return; m_product->m_part1 = part1; } void build_part2(int part2) { if (!m_product) return; m_product->m_part2 = part2; } void build_part3(int part3) { if (!m_product) return; m_product->m_part3 = part3; } public: Product* m_product; };
class ConcreteBuilderB : public Builder { public: ConcreteBuilderB(): Builder(), m_product(NULL) {} virtual void build_part() { if (!m_product) { m_product = new Product(); } } virtual Product* get_result() { return m_product; } void build_part1(int part1) { if (!m_product) return; m_product->m_part1 = part1 * 10; } void build_part2(int part2) { if (!m_product) return; m_product->m_part2 = part2 * 10; } void build_part3(int part3) { if (!m_product) return; m_product->m_part3 = part3 * 10; } public: Product* m_product; };
class Director { public: Product* construct(Builder& builder) { builder.build_part(); builder.build_part1(1); builder.build_part2(2); builder.build_part3(3); return builder.get_result(); } };
int main() { Product* product; Director director; ConcreteBuilderA builderA; ConcreteBuilderB builderB;
director.construct(builderA); product = builderA.get_result(); product->display(); delete product; product = NULL;
director.construct(builderB); product = builderB.get_result(); product->display(); delete product; product = NULL; system("Pause"); }
|
优点
- 将一个复杂对象的创建过程封装起来。
- 允许对象通过多个步骤来创建,并且可以改变过程(这和只有一个步骤的工厂模式不同)。
- 向客户隐藏产品内部的表现。
- 产品的实现可以被替换,因为客户只看到一个抽象的接口。
用途和缺点
- 经常被用来创建组合结构。
- 与工厂模式相比,采用生成器模式创建对象的客户,需要具备更多的领域知识。
相关模式
- Abstract Factory与Builder相似,因为它也可以创建复杂对象。主要的区别是Builder着重于一步步构造一个复杂对象,而Abstract Factory着重于多个系列的产品对象(简单的或是复杂的)。Builder在最后一步返回产品,而对于Abstract Factory来说,产品是立即返回的。
- Composite通常是用Builder生成的。
[1] 设计模式:可复用面向对象软件的基础
[2] Head First 设计模式