建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
优点: 1、建造者独立,易扩展。 2、便于控制细节风险。
缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。
- 创建一个表示食物条目和食物包装的接口。
/**
* 1. 创建一个表示食物条目和食物包装的接口。
* @author mazaiting
*/
public interface Item {
/**
* 名称
* @return
*/
public String name();
/**
* 包装
* @return
*/
public Packing packing();
/**
* 价格
* @return
*/
public float price();
}
/**
* 1. 包装接口
* @author mazaiting
*/
public interface Packing {
/**
* 包装
* @return
*/
public String pack();
}
- 创建实现 Packing 接口的实体类。
/**
* 2. 创建实现 Packing 接口的实体类。
* @author mazaiting
*/
public class Bottle implements Packing{
public String pack() {
return "Bottle";
}
}
/**
* 2. 创建实现 Packing 接口的实体类。
* @author mazaiting
*/
public class Wrapper implements Packing {
public String pack() {
return "Wrapper";
}
}
- 创建实现 Item 接口的抽象类,该类提供了默认的功能。
/**
* 3. 创建实现 Item 接口的抽象类,该类提供了默认的功能。
* @author mazaiting
*/
public abstract class Burger implements Item{
public Packing packing() {
return new Wrapper();
}
public abstract float price();
}
/**
* 3. 创建实现 Item 接口的抽象类,该类提供了默认的功能。
* @author mazaiting
*/
public abstract class Drink implements Item{
public Packing packing() {
return new Bottle();
}
public abstract float price();
}
- 创建扩展了 Burger的实体类。
/**
* 4. 创建扩展了 Burger的实体类。
* @author mazaiting
*
*/
public class ChickenBurger extends Burger{
public String name() {
return "Chicken Burger";
}
@Override
public float price() {
return 50.5f;
}
}
/**
* 4. 创建扩展了 Burger的实体类。
* @author mazaiting
*/
public class VegBurger extends Burger{
public String name() {
return "Veg Burger";
}
@Override
public float price() {
return 25.0f;
}
}
- 创建扩展了 ColdDrink 的实体类。
/**
* 5. 创建扩展了 ColdDrink 的实体类。
* @author mazaiting
*/
public class CokeDrink extends Drink{
public String name() {
return "Coke";
}
@Override
public float price() {
return 30.0f;
}
}
/**
* 5. 创建扩展了ColdDrink 的实体类。
* @author mazaiting
*/
public class PepsiDrink extends Drink{
public String name() {
return "Pepsi";
}
@Override
public float price() {
return 35.0f;
}
}
- 创建一个 Meal 类,带有上面定义的 Item 对象。创建一个 MealBuilder 类,实际的 builder 类负责创建 Meal 对象。
/**
* 6. 创建一个 Meal 类,带有上面定义的 Item 对象。
* @author mazaiting
*/
public class Meal {
private List<Item> items = new ArrayList<Item>();
/**
* 添加条目
* @param item
*/
private void addItem(Item item) {
items.add(item);
}
/**
* 获取总价格
* @return
*/
public float getCost() {
float cost = 0.0f;
for (Item item : items) {
cost += item.price();
}
return cost;
}
/**
* 显示条目详细信息
*/
public void showItems() {
for (Item item : items) {
System.out.print("Item : "+item.name());
System.out.print(", Packing : "+item.packing().pack());
System.out.println(", Price : "+item.price());
}
}
/**
* 创建一个 MealBuilder 类,实际的 builder 类负责创建 Meal 对象。
* @author mazaiting
*/
public static class MealBuilder{
private Meal mMeal = null;
public MealBuilder(){
mMeal = new Meal();
}
public MealBuilder prepareVegMeal() {
mMeal.addItem(new VegBurger());
mMeal.addItem(new CokeDrink());
return this;
}
public MealBuilder prepareNonVegMeal() {
mMeal.addItem(new ChickenBurger());
mMeal.addItem(new PepsiDrink());
return this;
}
public Meal show() {
return mMeal;
}
}
}
- 主函数调用
/**
* 7. 客户端验证
* @author mazaiting
*/
public class Client {
public static void main(String[] args) {
// 创建Meal对象, 链式播放
Meal meal = new Meal.MealBuilder()
.prepareVegMeal()
.prepareNonVegMeal()
.show();
// 显示条目
meal.showItems();
System.out.println("-----------------------");
// 打印价格
System.out.println("总价: " + meal.getCost());
}
}
打印结果:
Item : Veg Burger, Packing : Wrapper, Price : 25.0
Item : Coke, Packing : Bottle, Price : 30.0
Item : Chicken Burger, Packing : Wrapper, Price : 50.5
Item : Pepsi, Packing : Bottle, Price : 35.0
-----------------------
总价: 140.5