JAVA设计模式(三)
----------建造者模式
前言
什么是建造者模式呢?有一个经典的例子,那就是电脑组装。假如我们去中关村准备攒一台电脑,虽然我与其他消费者的需求不同,但组装师傅的组装流程都是大体相同,只不过每个部件具体操作不同(不同品牌的硬盘可能接口,电源线的安装方式不同),我们作为消费者可能并不关心这些,我们只知道大体流程就可以了(也就是对我们隐藏具体部件安装的细节)。这是一个多么经典的建造者例子啊。下面我们就顺着这条路,来进入建造者模式的世界。
建造者(Builder)模式的提出
我们在编码系统中经常遇到这样一种情况:一个复杂对象由几个部分(几个对象)组成,并且这些部分富于变化性,如果使用直观的设计方法,这些部件中的某一个的构建方式发生改变,都将导致整个对象的构件重新来过。建造者(Builder)模式引入就是为了将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
为什么使用?
是为了将构建复杂对象的过程和它的部件解耦.注意: 是解耦过程和部件.
因为一个复杂的对象,不但有很多大量组成部分,如汽车,有很多部件:车轮 方向盘 发动机还有各种小零件等等,部件很多,但远不止这些,如何将这些部件装配成一辆汽车,这个装配过程也很复杂(需要很好的组装技术),Builder模式就是为了将部件和组装过程分开.
使用示例
我们继续延续上面电脑组装的例子,对该模式的具体使用方式进行阐述。
示意关系图
建造者模式角色组成
如上图所示,大体分为以下4个部分:
抽象建造者
在这里要定义所有子部件的构造接口和一个取得最后成品的接口,在JAVA中通常由一个接口或者抽象类来表示。
/** * 抽象创建者 * @author Administrator */ public interface AbstractBuilder { public void buidePeripheralEquipment(); //组装外部设备 public void buildCPU(); public void buildMainBoard(); public void buildMemory(); public void buildDisplayCard(); public void buildHardDisk();
public Computer getComputer(); } |
具体建造者
创建者我们可以设想为某国际电脑品牌工厂(假设他们所有的电脑配件都是自己生产或者与其他品牌合资<现实中好像不存在>),所以创建者就要负责生产外部设备,CPU,主板,硬盘,内存,显卡……………
public class AMDBuilder implements AbstractBuilder { private Computer cp = new Computer(); //为了简便,我么就不去定义内存类,主板类,外设类。。。。。了 //代码种也省略了具体部件创建过程,零件配置中直接以String表示
public void buidePeripheralEquipment() { // TODO Auto-generated method stub cp.add("爱国者显示器 ,爱国者机箱电源 "); } public void buildCPU() { // TODO Auto-generated method stub cp.add("AMDX3800+ CPU"); } public void buildDisplayCard() { // TODO Auto-generated method stub cp.add("七彩虹GF92000显卡"); } public void buildHardDisk() { // TODO Auto-generated method stub cp.add("三星320G硬盘"); } public void buildMainBoard() { // TODO Auto-generated method stub cp.add("微星主板"); } public void buildMemory() { // TODO Auto-generated method stub cp.add("金士顿2G 800HZ"); } public Computer getComputer() { // TODO Auto-generated method stub return cp; } } |
指导者
指导者的任务就是把创建者生产出来的配件做一个统一的装配,装配好后再由建造者(工厂),提供给消费者。所以我们可以总结得到指导者只负责组装,不负责发货;创建者负责生产每个零件以及最后成品的发货。
public class ComputerDirector { private AbstractBuilder buider;
public ComputerDirector(AbstractBuilder buider) { this.buider = buider; } /* * 组装电脑 */ public void assembleComputer(){ buider.buidePeripheralEquipment(); buider.buildCPU(); buider.buildDisplayCard(); buider.buildHardDisk(); buider.buildMainBoard(); buider.buildMemory(); } } |
具体产品
通常就是文中涉及的那个分复的对象,本例中为电脑。
public class Computer { List elements = new ArrayList(); public void add(String childPart) { elements.add(childPart); } public void showChildren() { System.out.println("我的电脑配置如下 :"); for (int i = 0; i < elements.size(); i++) { System.out.println(elements.get(i)); } } } |
测试类
public class MyTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub AbstractBuilder buider = new AMDBuilder(); ComputerDirector director = new ComputerDirector(buider); director.assembleComputer(); Computer computer = buider.getComputer(); computer.showChildren(); } } |
打印结果如下:
我的电脑配置如下 : 爱国者显示器 ,爱国者机箱电源 AMDCPU 七彩虹GF92000显卡 三星320G硬盘 微星主板 金士顿2G 800HZ
|
注意要点
1.Builder模式 主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
2. Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动“。其缺点在于难以应对“分步骤构建算法”的需求变动。
3. 抽象工厂模式解决“系列对象”的需求变化,Builder模式解决“对象部分”的需求变化。
总结
创建者模式可以使产品内部表象独立化,在工厂方法中产品的内部构造是在产品内部定义的,而创建者模式是在Builder中定义的,这样定义一个新的创建者就可以改变产品的内部表象了。例如上面例子中,客户就不要爱国者的外设了,而需要一套三星的外部设备,这时只要修改我们AMDBuilder构建类,或者是添加一个新的创建者类(InterBuilder),然后在这个自定义构建类中定义我们需要的具体配件,而这些配件(子对象)构建出来的电脑对象的构建过程(指导者内的assembleComputer()方法)是不变的。
建造者模式可以对复杂对象的创建过程进行更加精确的控制,产品的组成是由指导者角色调用具体创建者角色逐步完成的,比起其它模式这种模式更能够体现出产品的构造过程。