假设直升飞机由机头, 机身, 机尾, 螺旋桨, 垂直起降系统组成. 战斗机由机头, 机身, 机尾, 喷气系统组成. 两种飞机的生产过程都是生产机头, 机身, 机尾, 螺旋桨/喷气系统, 垂直起降系统, 然后组装, (也就是说两种飞机的组成有一点区别, 但是生产步骤, 流程极为相似).
这个场景就符合Builder模式(使用相同的生产流程, 生产不同的飞机).
CPlaneDirector负责飞机部件的生产流程, 调用CPlanBuilder提供的接口.
CPlanBuilder提供生产各个部件接口.
CHelicopterBuilder和CBattlePlaneBuilder用于生产对应飞机部件的类.
CHelicopter和CBattlePlane 要生成的复杂对象(由各自的部件组成, 但是生成流程相同或者相似).
如图:
// 伪代码
pBuilder = new CHelicopterBuilder;
pCPlaneDirector = new CPlaneDirector(pBuilder)
// 调用生产流程函数
pCPlaneDirector->MakePlane(); // 这个函数封装了通用的生产流程
// 完成后, 飞机已经被生产出来, 使用builder返回飞机
CHelicopter* pCHelicopter = pBuilder->GetHelicopter();
// 上面的代码解耦的地方只有MakePlane (构建于表示分离)
1. 抓住Builder模式与Abstact Factory模式的区别是: Builder是同一个创建过程可以创建不同的表示; Abstract Factory 模式是可以创建一系列相关或相互依赖的对象, Builder模式强调的是同一个创建流程, Abstract Factory模式强调的是一系列.
2. 在设计时, 可能两个复杂的对象的生成流程不是完全一致的, 但是可以根据实际情况来折中, 例如直升飞机与战斗机的部件组成并没有完全一样, 在生成直升飞机时调用BuildWhiffSys()并没有任何意义, 但是为了生产流程的一致性, CBattlePlaneBuilder可以实现一个什么都不敢的BuildWhiffSys()函数. 这里更好的办法是在CPlaneBuilder实现什么都不做的"接口", 而具体的Builder更具它自己生产的对象的部件实现对应的接口.
3. 我始终觉得能为了模式而模式, 适合就好, 不能硬邦邦的套用模式, 要根据自己的实际情况而使用.