首页 > 代码库 > 深入浅出设计模式 ------ Builder(生成器)

深入浅出设计模式 ------ Builder(生成器)

一. 定义  将一个复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示。



二. 结构 

技术分享



三. 参与者

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();
    }  
}  



水果沙拉制作接口:规定制作沙拉方法, 具体实现交给实现类ConcreteFruitSaladBuilder

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注重于多个系列的产品的生产, 并且它是立即返回结果的。



参考书籍

              《设计模式:可复用面向对象软件的基础》



深入浅出设计模式 ------ Builder(生成器)