设计模式的学习(九):建造者模式
建造者模式
1、建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
2、例子
1、去KFC或者金拱门的时候大家一般都会点某种套餐,但是套餐中汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。 2、JAVA 中的 StringBuilder。
3、建造者模式的优缺点
优点: 1、建造者独立,易扩展。 2、便于控制细节风险。
缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。
4、代码
public class EntryptTest {
public static void main(String[] args) throws Exception {
MealBuder mealBuder = new MealBuder();
Meal chickenMeal = mealBuder.prepareChickenMeal();
System.out.println("Chicken Meal :");
chickenMeal.showItems();
System.out.println("Total Cost :" + chickenMeal.getCost());
Meal vegMeal = mealBuder.prepareVagMeal();
System.out.println("Veg Meal :");
vegMeal.showItems();
System.out.println("Veg Cost :" + vegMeal.getCost());
}
}
//创建一个食物条目接口
interface Item {
String name();
Packing packing();
float price();
}
//创建一个打包类型接口
interface Packing {
String packing();
}
//实现包装接口的具体类
class Wrapper implements Packing {
@Override
public String packing() {
return "Wrapper";
}
}
class Bottle implements Packing {
@Override
public String packing() {
return "Bottle";
}
}
//创建抽象类实现Item接口,提供了默认功能
abstract class Burger implements Item {
@Override
public Packing packing() {
return new Wrapper();
}
@Override
public abstract float price();
}
abstract class ColdDrink implements Item {
@Override
public Packing packing() {
return new Bottle();
}
@Override
public abstract float price();
}
//具体的商品类,扩展Burger和ColdDrink抽象类
class VegBurger extends Burger {
@Override
public String name() {
return "Veg Burger!";
}
@Override
public float price() {
return 25.0f;
}
}
class ChickenBurger extends Burger {
@Override
public String name() {
return "Chicken Burger!";
}
@Override
public float price() {
return 50.5f;
}
}
class Coke extends ColdDrink {
@Override
public String name() {
return "Coke";
}
@Override
public float price() {
return 30.0f;
}
}
class Pepsi extends ColdDrink {
@Override
public String name() {
return "Pepsi";
}
@Override
public float price() {
return 35.0f;
}
}
//创建一个Meal类,用来定制套餐
class Meal {
private List<Item> items = new ArrayList<>();
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() {
items.forEach(item -> {
System.out.print("Item :" + item.name());
System.out.print(" packing :" + item.packing());
System.out.println(" price :" + item.price());
});
}
}
//建造者用来创建具体的哪一类套餐
class MealBuder {
public Meal prepareVagMeal() {
Meal meal = new Meal();
meal.addItem(new VegBurger());
meal.addItem(new Coke());
return meal;
}
public Meal prepareChickenMeal() {
Meal meal = new Meal();
meal.addItem(new ChickenBurger());
meal.addItem(new Pepsi());
return meal;
}
}
分析:
我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(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。