建造者模式
1. 概念
建造者模式使用多个简单的对象一步一步构建成一个复杂的对象,建造者模式将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
在软件系统中,有时候面临着“一个复杂对象”的创建工作,该对象通常由若干子对象用一定的算法构成,由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。这时候使用建造者模式便比较好,通过一个Builder类(建造者)一步一步地去构造最终的对象,该Builder类是独立于其他对象的。
建造者模式与工厂模式的区别是,建造者模式更加关注零件装配的顺序。
2. 示例
以一个快餐店为例,一个典型的套餐是一个汉堡(Burger)和一杯冷饮(Cold drink),其中汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们被包在纸盒中;冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们被装在瓶子里。
我们以 Item
接口表示食物条目(汉堡、冷饮),以 Packing
接口表示食物包装(纸盒、瓶子)。
然后创建一个 Meal
类,带有 Item
的 ArrayList 和一个通过结合 Item 来创建不同类型的 Meal
对象的 MealBuilder
, BuilderPatternDemo
类使用 MealBuilder
来创建一个 Meal
。
创建一个表示食物条目和食物包装的接口
public interface Item { public String name(); public Packing packing(); public float price(); }
public interface Packing { public String pack(); }
创建实现
Packing
接口的实体类public class Wrapper implements Packing { @Override public String pack() { return "Wrapper"; } }
public class Bottle implements Packing { @Override public String pack() { return "Bottle"; } }
创建实现
Item
接口的抽象类,该类提供了默认的功能public abstract class Burger implements Item { @Override public Packing packing() { return new Wrapper(); } @Override public abstract float price(); }
public abstract class ColdDrink implements Item { @Override public Packing packing() { return new Bottle(); } @Override public abstract float price(); }
创建扩展了
Burger
和ColdDrink
的实体类public class VegBurger extends Burger { @Override public float price() { return 25.0f; } @Override public String name() { return "Veg Burger"; } }
public class ChickenBurger extends Burger { @Override public float price() { return 50.5f; } @Override public String name() { return "Chicken Burger"; } }
public class Coke extends ColdDrink { @Override public float price() { return 30.0f; } @Override public String name() { return "Coke"; } }
public class Pepsi extends ColdDrink { @Override public float price() { return 35.0f; } @Override public String name() { return "Pepsi"; } }
创建一个
Meal
类,带有上面定义的Item
对象import java.util.ArrayList; import java.util.List; public class Meal { private List<Item> items = new ArrayList<Item>(); public void addItem(Item item){ items.add(item); } 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
对象public class MealBuilder { public Meal prepareVegMeal (){ Meal meal = new Meal(); meal.addItem(new VegBurger()); meal.addItem(new Coke()); return meal; } public Meal prepareNonVegMeal (){ Meal meal = new Meal(); meal.addItem(new ChickenBurger()); meal.addItem(new Pepsi()); return meal; } }
BuiderPatternDemo
使用MealBuilder
来演示建造者模式(Builder Pattern)public class BuilderPatternDemo { public static void main(String[] args) { MealBuilder mealBuilder = new MealBuilder(); Meal vegMeal = mealBuilder.prepareVegMeal(); System.out.println("Veg Meal"); vegMeal.showItems(); System.out.println("Total Cost: " +vegMeal.getCost()); Meal nonVegMeal = mealBuilder.prepareNonVegMeal(); System.out.println("\n\nNon-Veg Meal"); nonVegMeal.showItems(); System.out.println("Total Cost: " +nonVegMeal.getCost()); } }
// 执行程序,输出结果 Veg Meal Item : Veg Burger, Packing : Wrapper, Price : 25.0 Item : Coke, Packing : Bottle, Price : 30.0 Total Cost: 55.0 Non-Veg Meal Item : Chicken Burger, Packing : Wrapper, Price : 50.5 Item : Pepsi, Packing : Bottle, Price : 35.0 Total Cost: 85.5