1、建造者模式的基本概念
建造者模式的最初定义是:将一个复杂对象的创建与它的表示分离,使得同样的创建过程可以创建不同的表示。
我们一起来理解一下这句话,首先第一词语是复杂对象,什么是复杂对象,就是这个对象的生成过程不是new int这样一下就行了,是在对象的生成过程中间去配置对象的属性,所谓属性就是成员变量,之所以说复杂是因为可能有很多成员变量需要赋值。或者是成员变量不多,但是成员变量本身是一个“”复杂“对象”,内部有很多成员变量需要赋值。下一个词语是“表示”,所谓表示指的就是展现给别人看时的样子,也就是其展现出来的功能。这句话用自己的理解来讲述的话就是:一个对象内部带有的属性有很多需要配置的地方,就称之为复杂对象。复杂对象的配置方法和执行这些方法的行为是分开实现的,这样的对象在生成过程中就可以灵活的给予不同配置,根据其其配置的不同,展现出来的功能也是不一样的。同一套配置方法,由于配置方法的执行个数、执行内容和执行顺序不同,装配出来的对象实现功能也不同。
2、代码案例与分析
考虑这样的一个场景:一个产品,内部有一个零件装配清单;通过不同方式的装配能够呈现出不同的产品,代码的实现过程如下:
1 //建造者模式 2 #include <iostream> 3 #include"string" 4 #include"list" 5 using namespace std; 6 7 //产品:提供零件装配清单和装配方法,但不执行装配方法 8 class Product 9 { 10 list <string>m_list; 11 public: 12 void add(string component) 13 { 14 m_list.push_back(component); 15 } 16 void show() 17 { 18 for(list<string>::iterator iter=m_list.begin();iter!=m_list.end();iter++) 19 { 20 cout<<*iter<<endl; 21 }; 22 }; 23 }; 24 25 //建造者:内部含有产品雏形,装配方法的执行者,但是不启动装配 26 class Builder1 27 { 28 private: 29 Product m_product; 30 public: 31 void BuilderPartA() 32 { 33 m_product.add("A零件部分"); 34 }; 35 void BuilderPartB() 36 { 37 m_product.add("B零件部分"); 38 }; 39 void BuilderPartC() 40 { 41 m_product.add("C零件部分"); 42 }; 43 Product& getReasult() 44 { 45 return m_product; 46 }; 47 }; 48 49 //指挥官:启动装配过程,决定具体的装配顺序 50 class Director 51 { 52 public: 53 void BuiderOder(Builder1* m_builder1Ptr) 54 { 55 m_builder1Ptr->BuilderPartA(); 56 m_builder1Ptr->BuilderPartB(); 57 m_builder1Ptr->BuilderPartC(); 58 } 59 }; 60 //客户端 61 int main() 62 { 63 Builder1 m_builder1; 64 Director m_director; 65 cout<<"开始制造产品"<<endl; 66 m_director.BuiderOder(&m_builder1); 67 m_builder1.getReasult().show(); 68 69 getchar(); 70 return 0; 71 }
代码执行结果:
代码分析:从代码的实现过程可以发现,建造者模式的核心角色一共有三个:产品类、建造者类和指挥官类。产品类含有装配方法,但是不行;建造者能够执行装配方法,但是不负责启动;指挥官类负责启动建造者进行装配,并且规定了装配顺序。在客户端可以发现,只要声明指挥官对象和建造者对象,并把建造者对象传递给指挥官对象就行,就能通过建造者类的getReasult()函数得到装配好的产品。那这样做有什么好处呢?我们想象看指挥官类是可以决定产品的装配内容和顺序,在产品类不变的情况下,只要修改装配的内容和顺序,就可以呈现出不同的产品功能。所以建造者模式就非常适用于对象内容灵活多变的情况,如果用传统的方法,由于其灵活多变的内容可能就需要拆分成不同的实现类,但是利用建造者模式,就可以通过指挥官来选择装配方法和装配顺序来生产出同一类型但是具有不同功能的对象。
3、类图总结
4、建造者模式的优缺点和适用场景
优点:
客户端与产品的具体创建过程分离。同一种创建过程可以生成不同功能的对象。
建造者可以进行替换或者再增加新的建造者。方便代码的修改和功能拓展。
职责单一。让代码更加清晰,方便阅读理解,方便测试。
缺点
当产品的变化很大时,需要增加很多建造者去适应变化,使得代码庞大。因此,只能限制于产品变化较小的情况下使用。
使用场景:
一个对象的生成需要多个零件组装时,并且不同组装顺序会产生不同的结果
5、关键点记忆
学习完一种设计模式可能很快就会淡忘,记住关键词“灵活组装”,然后进一步回忆:组装谁?组装产品对象;谁组装?指挥官负责执行顺序,建造者负责执行组装,产品类提供组装方法。调用不同建造者或者指挥官会生产不同功能的产品,因为建造者决定了执行组装,指挥官决定了组装顺序,所以称之为“”灵活“”组装。