(2.2.2 伪装配厂/建造者模式)
工厂模式中描述的,是工厂能够直接提供产品的模式。本节讲述的装配厂模式/建造者模式,则由于产品较复杂因而不再简单的提供,builder/装配厂/建造者需要一个指导者说明装配过程,指导者调度(员) /director。(实际工厂的车间中,都有一个调度)
2.2 装配厂模式
2.2.1 串接式setter模式 如StringBuilder,参见Effective Java。
2.2.2 伪 装配厂模式 最2 的伪建造者模式
2.2.3 真正的装配厂模式
伪装配厂模式
在一些关于设计模式的书籍中,讲解建造者模式的例子和演示程序,并非GoF所称的建造者模式(3.2),例如一些人和书籍中使用的游戏角色设计例子,事实上使用的是工厂方法+模板方法模式【参见[3.3模板方法模式(5.10)】。之所以称之为伪装配厂模式,因为它的适用场景和装配厂模式相似。
产品类型已知型装配厂模式(伪 装配厂模式):它建造的产品,可以有各种不同的部件,但产品属于同一种类型。
以电脑/MyPC的装配为例。电脑是一个完整的复杂产品,它包含多个成员变量表示的对象,这些成员变量可以称为产品的部件或零件,如CUP、显示器/ Display和硬盘/ HD。你可以将这些部件设计成抽象类,如CUP有Intel和AMD子类,使得更有代表性。MyPC及其部件,我们将它们放在package creational.builder.pc包中。
例程 2 9模板方法 package creational.builder.pseudoBuilder; import creational.builder.pc.*; public abstract class PCBuilder{ public void addCPU(){} public void addDisplay(){} public void addHD(){} public abstract MyPC getResult(); public void construct(){ addCPU(); addDisplay(); addHD(); } }注意:PCBuilder中定义了一个abstract MyPC getResult(),这是 工厂方法。
配机器的小白现在可以买装机的结果了。
package creational.builder.pseudoBuilder; import creational.builder.pc.*; import tool.God; /** * 配机器的小白 * * @author yqj2065 * @version 0.1 */ public class Client{ public static void main(String args[]) { PCBuilder b = (PCBuilder)God.create("2-9-Builder"); b.construct(); MyPC pc = b.getResult(); System.out.println(pc); } public static void test(){ PCDirector director = new PCDirector("2-9-Builder"); MyPC pc = director.construct(); System.out.println(pc); } }
本来,这是使用了工厂方法+模板方法的这种多种设计模式的组合应用的典型例子,值得学习。
然而,有人对照GoF的建造者模式,生编硬造地按照建造者模式(3.2)的类图,将模板方法封装到调度(员) /Director类中,就曲解了建造者模式(3.2)的“适用性”。
下面是某些书籍中的Director:
package creational.builder.pseudoBuilder; import creational.builder.pc.*; /** * 生编硬造 */ public class PCDirector{ private PCBuilder b; public PCDirector(String builder){ this.b = b ; } public MyPC construct(){ b.addCPU(); b.addDisplay(); b.addHD(); return b.getResult(); } }可以用Client.test()测试。如此编程, Client可以仅仅依赖于调度(员) /Director,如图2-4所示。有人说,Director相当于装配店的销售人员,此实现使得 Client与Build隔离。(但是,建造者模式的本意是 产品的构建过程construct()与产品类型的隔离。)
伪装配厂模式的核心将PCBuilder定义的装配电脑的流程construct()搬到Director中。
此时,调度(员)能够发挥作用的场合,是存在多种Director,它们封装对象构成的算法。例如买一碗牛肉粉,客户给出一些参数——嘱咐加或不加葱、加多少辣椒。调度(员) /Director的construct()描述该需求并让任意的牛肉粉生产者照此办理;另外的客户则可能需要另一个construct()。
在伪装配厂模式中,Director应用策略模式(封装抽象的construct()方法)、Director的子类应用模板方法模式,而PCBuilder应用工厂方法模式。
伪装配厂模式具有如下特点: