一. 定义 将一个复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示。
二. 结构
三. 参与者
Builder : 为创建一个Product对象的各个部件指定抽象接口。
ConcreteBuilder : 实现Builder的接口以构造和装配该产品的各个部件。定义并明确它所创建的表示。提供一个检索产品的接口。
Director : 构造一个使用(聚合:has-a的关系)Builder接口的对象。如下文代码ChefDirector类。
Product : 表示被构造的复杂对象。ConcreateBuilder创建该产品的内部表示并定义它的装配过程。包含定义组成部件的类, 包括将这些部件装配成最终产品的接口。
四. 时序图
从图中可以看出来Builder模式一个特点就是将内容集中生成, 然后输出。 常见例子就是StringBuilder的append方法, 一直append, 然后最终生成一个String。
五. 代码实现:
厨师作为水果沙拉的制作指挥者, 下令做沙拉, 具体细节不管。
package com.wenniuwuren.builder;
/**
* 厨师指挥者类
* @author wenniuwuren
*
*/
public class ChefDirector {
private FruitSaladBuilder fruitSaladBuilder;
// 持有当前所需要的构建器对象
public ChefDirector (FruitSaladBuilder fruitSaladBuilder) {
this.fruitSaladBuilder = fruitSaladBuilder;
}
// 制造水果沙拉
public void constructFruitSalad() {
fruitSaladBuilder.buildSalad();
fruitSaladBuilder.buildApple();
fruitSaladBuilder.buildWaterMelon();
}
}
package com.wenniuwuren.builder;
/**
* 制作水果沙拉接口
* @author wenniuwuren
*
*/
public interface FruitSaladBuilder {
// 添入沙拉酱
public void buildSalad();
// 添入西瓜
public void buildWaterMelon();
// 加入苹果
public void buildApple();
// 便于Client得到最后的Result
public FruitSaladProduct getFruitSaladProduct();
}
package com.wenniuwuren.builder;
/**
* 实际制作沙拉
* @author wenniuwuren
*
*/
public class ConcreteFruitSaladBuilder implements FruitSaladBuilder {
FruitSaladProduct fruitSaladProduct = new FruitSaladProduct();
// 添入沙拉酱
public void buildSalad() {
fruitSaladProduct.setSalad("沙拉酱");
}
// 添入西瓜
public void buildWaterMelon() {
fruitSaladProduct.setWatermelon("西瓜");
}
// 加入苹果
public void buildApple() {
fruitSaladProduct.setApple("苹果");
}
// 便于Client得到最后的Result
@Override
public FruitSaladProduct getFruitSaladProduct() {
return fruitSaladProduct;
}
}
水果沙拉产品: 保存着制作水果沙拉的水果种类
package com.wenniuwuren.builder;
/**
* FruitSalad产品
* @author wenniuwuren
*
*/
public class FruitSaladProduct {
private String apple;
private String watermelon;
private String salad;
public String getApple() {
return apple;
}
public void setApple(String apple) {
this.apple = apple;
}
public String getWatermelon() {
return watermelon;
}
public void setWatermelon(String watermelon) {
this.watermelon = watermelon;
}
public String getSalad() {
return salad;
}
public void setSalad(String salad) {
this.salad = salad;
}
}
package com.wenniuwuren.builder;
/**
* 测试类
* @author wenniuwuren
*
*/
public class Client {
public static void main(String[] args) {
FruitSaladBuilder appleSaladBuilder = new ConcreteFruitSaladBuilder();
// Builder当成参数传入接受指挥
ChefDirector chefDirector = new ChefDirector(appleSaladBuilder);
// 内部连续添加材料
chefDirector.constructFruitSalad();
// 一次性输出
FruitSaladProduct fruitSaladProduct = appleSaladBuilder
.getFruitSaladProduct();
System.out.println("沙拉的配料是:" + fruitSaladProduct.getSalad() + ", "
+ fruitSaladProduct.getWatermelon() + ", "
+ fruitSaladProduct.getApple());
}
}
输出结果:
沙拉的配料是:沙拉酱, 西瓜, 苹果
正如上述代码实现, Builder设计模式将具体的实现隐藏在Builder中, 指挥者Director无需关心细节。 这个和Abstract Factory很相似, 但是区别在于Builder在于一步步构造对象, 最后一次性输出, 而Abstract Factory注重于多个系列的产品的生产, 并且它是立即返回结果的。
参考书籍
《设计模式:可复用面向对象软件的基础》