建造者模式
建造者模式是一种创建型设计模式,它允许你创建复杂对象的步骤与表示方式相分离。
建造者模式是一种创建型设计模式,它的主要目的是将一个复杂对象的构建过程与其表示相分离,从而可以创建具有不同表示形式的对象。
主要解决
在软件系统中,一个复杂对象的创建通常由多个部分组成,这些部分的组合经常变化,但组合的算法相对稳定。
何时使用
当一些基本部件不变,而其组合经常变化时。
如何解决
将变与不变的部分分离开。
类图示例

举个例子
我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)。汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸盒中。冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子中。
我们将创建一个表示食物条目(比如汉堡和冷饮)的 Item 接口和实现 Item 接口的实体类,以及一个表示食物包装的 Packing 接口和实现 Packing 接口的实体类,汉堡是包在纸盒中,冷饮是装在瓶子中。
然后我们创建一个 Meal 类,带有 Item 的 ArrayList 和一个通过结合 Item 来创建不同类型的 Meal 对象的 MealBuilder。BuilderPatternDemo 类使用 MealBuilder 来创建一个 Meal。
设计类图

代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
| import java.util.ArrayList; import java.util.List;
interface Item { public String name();
public Packing packing();
public int price(); }
interface Packing { public String pack(); }
class Wrapper implements Packing { public String pack() { return "Wrapper"; } }
class Bottle implements Packing { public String pack() { return "Bottle"; } }
abstract class Burger implements Item { public Packing packing() { return new Wrapper(); }
public abstract int price(); }
abstract class ColdDrink implements Item { public Packing packing() { return new Bottle(); }
public abstract int price(); }
class VegetableBurger extends Burger { public int price() { return 25; }
public String name() { return "Vegetable Burger"; } }
class ChickenBurger extends Burger { public int price() { return 30; }
public String name() { return "Chicken Burger"; } }
class Coke extends ColdDrink { public int price() { return 10; }
public String name() { return "Coke"; } }
class Pepsi extends ColdDrink { public int price() { return 10; }
public String name() { return "Pepsi"; } }
class Meal { private List<Item> items = new ArrayList<Item>();
public void addItem(Item item) { items.add(item); }
public int getCost() { int cost = 0; 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()); System.out.println(", Price: " + item.price()); } } }
class MealBuilder { public Meal PrepareVegetableBurger() { Meal meal = new Meal(); meal.addItem(new VegetableBurger()); meal.addItem(new Coke()); return meal; }
public Meal prepareChickenBurger() { Meal meal = new Meal(); meal.addItem(new ChickenBurger()); meal.addItem(new Pepsi()); return meal; } }
public class Builder { public static void main(String[] args) { MealBuilder builder = new MealBuilder(); Meal cb = builder.prepareChickenBurger(); System.out.println("Chicken Burger: "); cb.showItems(); System.out.println("Total cost: " + cb.getCost());
Meal vb = builder.PrepareVegetableBurger(); System.out.println("Vegetable Burger: "); vb.showItems(); System.out.println("Total cost: " + vb.getCost()); } }
|
建造者模式包含如下角色
- Builder(抽象建造者),抽象建造者为创建一个产品Product对象的各个部件指定抽象接口,在该接口中一般声明两类方法,一类方法是buildPartX(),它们用于创建复杂对象的各个部件;另一类方法是getResult(),它们用于返回复杂对象。它既可以是抽象类,也可以是接口。
- ConcreteBuilder(具体建造者),具体建造者实现了Builder接口,实现各个部件的构造和装配方法,定义并明确它所创,建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。
- Product(产品角色),产品角色是被构建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示,并定义它的装配过程。
- Director(指挥者),指挥者又称为导演类,它负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,可以在其construct()建造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造。客户端一般只需要与指挥者进行交互,在客户端确定具体建造者的类型, 并实例化具体建造者对象(也可以通过配置文件和反射机制),然后通过指挥者类的构造函数或者Setter方法将该对象传人指挥者类中。
模式分析
优点
- 分离构建过程和表示,使得构建过程更加灵活,可以构建不同的表示。
- 可以更好地控制构建过程,隐藏具体构建细节。
代码复用性高,可以在不同的构建过程中重复使用相同的建造者。
缺点
- 如果产品的属性较少,建造者模式可能会导致代码冗余。
- 增加了系统的类和对象数量。