您的位置:首页 > 产品设计 > UI/UE

设计模式之四 --- 建造(Builder)模式

2012-03-09 13:55 411 查看
【1】基本概念

建造(Builder)模式是一种对象构建的设计模式,它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。

【2】简单分析

我们先来看一下该设计模式的UML结构图



上图是Strategy 模式的结构图,让我们可以进行更方便的描述:

Builder

为创建一个Product对象的各个部件指定抽象接口。

ConcreteBuilder

实现Builder的接口以构造和装配该产品的各个部件。
定义并明确它所创建的表示。
提供一个检索产品的接口

Director

构造一个使用Builder接口的对象。

Product

表示被构造的复杂对象。ConcreateBuilder创建该产品的内部表示并定义它的装配过程。
在以下情况使用生成器模式:

包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

当创建复杂对象(这些对象内部构建间的建造顺序通常是稳定的)的算法应该独立于该对象的组成部分以及它们的装配方式时;

当构造过程必须允许被构造的对象有不同的表示时。

【3】如何用java语言来实现该模式

下面以一个简单的例子来展示该模式,先看下代码结构图:



3.1 先创建一个Product类--产品类:

[html]
view plaincopyprint?

package com.andyidea.patterns.product;

/**
* Product--产品类
* @author Andy.Chen
*
*/
public class Pizza {

private String dough;
private String sauce;
private String topping;

public void setDough(String dough) {
this.dough = dough;

}
public void setSauce(String sauce) {
this.sauce = sauce;

}
public void setTopping(String topping) {
this.topping = topping;

}

}

[html] 
view plaincopyprint?

package com.andyidea.patterns.builder; 

import com.andyidea.patterns.product.Pizza; 

/** 
* Builder类--抽象建造者类 
* @author Andy.Chen 
* 
*/ 
public abstract class PizzaBuilder { 

protected Pizza pizza; 

public Pizza getPizza() { 
return pizza; 
} 

public void createNewPizzaProduct() { 
pizza = 
new Pizza(); 
} 

public abstract void buildDough(); 
public abstract void buildSauce(); 
public abstract void buildTopping(); 

} 

package com.andyidea.patterns.builder;

import com.andyidea.patterns.product.Pizza;

/**
 * Builder类--抽象建造者类
 * @author Andy.Chen
 *
 */
public abstract class PizzaBuilder {
	
    protected Pizza pizza;
   
    public Pizza getPizza() { 
    	return pizza; 
    }
    
    public void createNewPizzaProduct() { 
    	pizza = new Pizza(); 
    }
 
    public abstract void buildDough();
    public abstract void buildSauce();
    public abstract void buildTopping();

}
3.3 创建具体建造者类

HawaiianPizzaBuilder.java源码:

[html]
view plaincopyprint?

package com.andyidea.patterns.concretebuilder;

import com.andyidea.patterns.builder.PizzaBuilder;

/**
* ConcreteBuilder类--具体建造者类
* @author Andy.Chen
*
*/
public class HawaiianPizzaBuilder extends PizzaBuilder {

@Override
public void buildDough() {
System.out.println("Hawaiian-Dough");
pizza.setDough("Hawaiian-Dough");
}

@Override
public void buildSauce() {
System.out.println("Hawaiian-Sauce");
pizza.setSauce("Hawaiian-Sauce");
}

@Override
public void buildTopping() {
System.out.println("Hawaiian-Topping");
pizza.setTopping("Hawaiian-Topping");
}

}

[html] 
view plaincopyprint?

package com.andyidea.patterns.concretebuilder; 

import com.andyidea.patterns.builder.PizzaBuilder; 

/** 
* ConcreteBuilder类--具体建造者类 
* @author Andy.Chen 
* 
*/ 
public class SpicyPizzaBuilder extends PizzaBuilder { 

@Override 
public void buildDough() { 
System.out.println("Spicy-Dough"); 
pizza.setDough("Spicy-Dough"); 
} 

@Override 
public void buildSauce() { 
System.out.println("Spicy-Sauce"); 
pizza.setSauce("Spicy-Sauce"); 
} 

@Override 
public void buildTopping() { 
System.out.println("Spicy-Topping"); 
pizza.setTopping("Spicy-Topping"); 
} 

} 

package com.andyidea.patterns.concretebuilder;

import com.andyidea.patterns.builder.PizzaBuilder;

/**
 * ConcreteBuilder类--具体建造者类
 * @author Andy.Chen
 *
 */
public class SpicyPizzaBuilder extends PizzaBuilder {

	@Override
	public void buildDough() {
		System.out.println("Spicy-Dough");
		pizza.setDough("Spicy-Dough");
	}

	@Override
	public void buildSauce() {
		System.out.println("Spicy-Sauce");
		pizza.setSauce("Spicy-Sauce");
	}

	@Override
	public void buildTopping() {
		System.out.println("Spicy-Topping");
		pizza.setTopping("Spicy-Topping");
	}

}
3.4 创建指挥者(Director)类:Waiter.java

[html]
view plaincopyprint?

package com.andyidea.patterns.director;

import com.andyidea.patterns.builder.PizzaBuilder;
import com.andyidea.patterns.product.Pizza;

/**
* Director类--指挥者类
* @author Andy.Chen
*
*/
public class Waiter {

private PizzaBuilder pizzaBuilder;

public void setPizzaBuilder (PizzaBuilder pb) {
pizzaBuilder = pb;

}

public Pizza getPizza() {
return pizzaBuilder.getPizza();
}

public void constructPizza() {
pizzaBuilder.createNewPizzaProduct();
pizzaBuilder.buildDough();
pizzaBuilder.buildSauce();
pizzaBuilder.buildTopping();
}
}

[html] 
view plaincopyprint?

package com.andyidea.patterns.client; 

import com.andyidea.patterns.builder.PizzaBuilder; 
import com.andyidea.patterns.concretebuilder.HawaiianPizzaBuilder; 

import com.andyidea.patterns.concretebuilder.SpicyPizzaBuilder;

import com.andyidea.patterns.director.Waiter; 
import com.andyidea.patterns.product.Pizza; 

public class BuilderClient { 

public static void main(String[] args) { 

System.out.println("Welcome to Andy.Chen Blog!" +"\n" 

+"Builder Patterns." +"\n"); 

Waiter waiter = new Waiter();

PizzaBuilder hawaiian_pizzabuilder =
new HawaiianPizzaBuilder(); 

PizzaBuilder spicy_pizzabuilder =
new SpicyPizzaBuilder(); 

System.out.println("------------HawaiianPizza------------"); 
waiter.setPizzaBuilder(hawaiian_pizzabuilder); 
waiter.constructPizza(); 

System.out.println("------------SpicyPizza------------"); 
waiter.setPizzaBuilder(spicy_pizzabuilder); 
waiter.constructPizza(); 

Pizza pizza = waiter.getPizza();

} 
} 

package com.andyidea.patterns.client;

import com.andyidea.patterns.builder.PizzaBuilder;
import com.andyidea.patterns.concretebuilder.HawaiianPizzaBuilder;
import com.andyidea.patterns.concretebuilder.SpicyPizzaBuilder;
import com.andyidea.patterns.director.Waiter;
import com.andyidea.patterns.product.Pizza;

public class BuilderClient {

	public static void main(String[] args) {
		
		System.out.println("Welcome to Andy.Chen Blog!" +"\n" 
		           +"Builder Patterns." +"\n");
		
	    Waiter waiter = new Waiter();
	    PizzaBuilder hawaiian_pizzabuilder = new HawaiianPizzaBuilder();
	    PizzaBuilder spicy_pizzabuilder = new SpicyPizzaBuilder();
	 
		System.out.println("------------HawaiianPizza------------");
	    waiter.setPizzaBuilder(hawaiian_pizzabuilder);
	    waiter.constructPizza();
	    
	    System.out.println("------------SpicyPizza------------");
	    waiter.setPizzaBuilder(spicy_pizzabuilder);
	    waiter.constructPizza();
	 
	    Pizza pizza = waiter.getPizza();
	}
}
【4】程序运行结果:

[html]
view plaincopyprint?

Welcome to Andy.Chen Blog!
Builder Patterns.

------------HawaiianPizza------------
Hawaiian-Dough
Hawaiian-Sauce
Hawaiian-Topping
------------SpicyPizza------------
Spicy-Dough
Spicy-Sauce
Spicy-Topping

Welcome to Andy.Chen Blog!
Builder Patterns.

------------HawaiianPizza------------
Hawaiian-Dough
Hawaiian-Sauce
Hawaiian-Topping
------------SpicyPizza------------
Spicy-Dough
Spicy-Sauce
Spicy-Topping通过上面我们可以看到:建造者模式的好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: