建造者模式(builder)
定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
UML图
成员介绍
抽象建造者(Builder)角色:给 出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者 (ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的两种方法:一种是建造方法(buildPart1和 buildPart2),另一种是返还结构方法(retrieveResult)。一般来说,产品所包含的零件数目与建造方法的数目相符。换言之,有多少 零件,就有多少相应的建造方法。
具体建造者(ConcreteBuilder)角色:担任这个角色的是与应用程序紧密相关的一些类,它们在应用程序调用下创建产品的实例。这个角色要完成的任务包括:1.实现抽象建造者Builder所声明的接口,给出一步一步地完成创建产品实例的操作。2.在建造过程完成后,提供产品的实例。
导演者(Director)角色:担任这个角色的类调用具体建造者角色以创建产品对象。应当指出的是,导演者角色并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者角色。
产品(Product)角色:产品便是建造中的复杂对象。一般来说,一个系统中会有多于一个的产品类,而且这些产品类并不一定有共同的接口,而完全可以是不相关联的。
例子
builder类
package com.csdhsm.pattemdesign.builder; /** * @Title: Builder.java * @Description: Builder类 * @author: Han * @date: 2016年6月23日 下午8:18:45 */ public abstract class Builder { public abstract void buildPartA(); public abstract void buildPartB(); public abstract Product getResult(); }
具体建造者类
package com.csdhsm.pattemdesign.builder; /** * @Title: ConcreteBuilder1.java * @Description: 具体建造1 * @author: Han * @date: 2016年6月23日 下午8:19:23 */ public class ConcreteBuilder1 extends Builder { private Product product = new Product(); @Override public void buildPartA() { product.add("部件A"); } @Override public void buildPartB() { product.add("部件B"); } @Override public Product getResult() { return product; } }
package com.csdhsm.pattemdesign.builder; /** * @Title: ConcreteBuilder2.java * @Description: 具体建造2 * @author: Han * @date: 2016年6月23日 下午8:19:40 */ public class ConcreteBuilder2 extends Builder { private Product product = new Product(); @Override public void buildPartA() { product.add("部件X"); } @Override public void buildPartB() { product.add("部件Y"); } @Override public Product getResult() { return product; } }
指挥者类
package com.csdhsm.pattemdesign.builder; /** * @Title: Director.java * @Description: 指挥者类 * @author: Han * @date: 2016年6月23日 下午8:20:06 */ public class Director { public void construct(Builder builder) { builder.buildPartA(); builder.buildPartB(); } }
产品类
package com.csdhsm.pattemdesign.builder; import java.util.ArrayList; import java.util.List; /** * @Title: Product.java * @Description: 产品类 * @author: Han * @date: 2016年6月23日 下午8:20:30 */ public class Product { List<String> parts = new ArrayList<>(); public void add(String part) { parts.add(part); } public void show() { System.out.println("产品 创建 ----"); for (String part : parts) { System.out.println(part); } } }
客户端
package com.csdhsm.pattemdesign.builder; public class Solution { public static void main(String[] args) { Director director = new Director(); Builder b1 = new ConcreteBuilder1(); Builder b2 = new ConcreteBuilder2(); director.construct(b1); Product p1 = b1.getResult(); p1.show(); director.construct(b2); Product p2 = b2.getResult(); p2.show(); } }
总结
在什么情况下使用建造模式
1. 需要生成的产品对象有复杂的内部结构,每一个内部成分本身可以是对象,也可以仅仅是一个对象(即产品对象)的一个组成部分。
2. 需要生成的产品对象的属性相互依赖。建造模式可以强制实行一种分步骤进行的建造过程,因此,如果产品对象的一个属性必须在另一个属性被赋值之后才可以被赋值,使用建造模式是一个很好的设计思想。
3. 在对象创建过程中会使用到系统中的其他一些对象,这些对象在产品对象的创建过程中不易得到。