1. 建造者模式概述
使用多个简单对象来构造一个复杂的对象。
(1) 适用情况
构造一个复杂对象的内部组件不变,但是这些内部组建的组合方式经常变化的时候,可以考虑使用建造者模式。
(2) 优点
建造者独立,易扩展
(3) 缺点
- 产品必须有共同点,范围有限制
- 不适用于内部组件经常发生变动的情况
2. 建造者模式实例
我们现在要设计一个简单的外卖系统,系统中提供各种套餐,套餐中可以包含食物和饮料。
(1) 先实现一个Item类,表示所有的食物和饮料的基类,它还实现了Packing接口,这样每个Item就可以进行打包了
public abstract class Item implements Packing {
// 物品名称
private String name;
// 物品价格
private int price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
public interface Packing {
// 打包
String packing();
}
(2) 外卖中可以包括食物Food和饮料Drink,它们都继承于Item类,且实现不同的打包方式
public abstract class Food extends Item implements Box {
// 食物是用盒子打包
}
public abstract class Drink extends Item implements Bottle {
// 饮料是用瓶子打包
}
(3) 打包方式可以分为盒装和瓶装
public interface Box extends Packing {
@Override
default String packing() {
// 盒装
return "Box";
}
}
public interface Bottle extends Packing {
@Override
default String packing() {
// 瓶装
return "Bottle";
}
}
(4) 实现具体的食物和饮料
public class Rice extends Food {
public Rice() {
// 米饭价格15元
this.setName("Rice");
this.setPrice(15);
}
}
public class Noodles extends Food{
public Noodles() {
// 面条价格12元
this.setName("Noodles");
this.setPrice(12);
}
}
public class Coke extends Drink {
public Coke() {
// 可乐价格4元
this.setName("Coke");
this.setPrice(4);
}
}
public class Spirit extends Drink {
public Spirit() {
// 雪碧价格3元
this.setName("Spirit");
this.setPrice(3);
}
}
(5) 实现套餐类
public class Meal {
private List<Item> items = new ArrayList<>();
// 打印套餐总价
public void printCost() {
int cost = 0;
for (Item item : items) {
cost += item.getPrice();
}
System.out.println("Cost: " + cost);
}
// 打印套餐内容
public void printItems() {
for (Item item : items) {
System.out.print("Item: " + item.getName());
System.out.print(", Packing: " + item.packing());
System.out.println(", Price : " + item.getPrice());
}
}
// 套餐增加内容
public void addItem(Item item) {
this.items.add(item);
}
}
(6) 实现套餐的建造者类
public class MealBuilder {
public Meal buyMeal1() {
Meal meal = new Meal();
meal.addItem(new Rice());
meal.addItem(new Coke());
return meal;
}
public Meal buyMeal2() {
Meal meal = new Meal();
meal.addItem(new Noodles());
meal.addItem(new Spirit());
return meal;
}
}
(7) 点外卖
public class BuilderPatternDemo {
public static void main(String[] args) {
MealBuilder builder = new MealBuilder();
Meal meal1 = builder.buyMeal1();
meal1.printItems();
meal1.printCost();
Meal meal2 = builder.buyMeal2();
meal2.printItems();
meal2.printCost();
}
}
3. 一些思考
这个例子中的复杂对象就是套餐,而简单对象就是各种食物和饮料。
它们都是派生自Item类,即都有共同点。
食物和饮料不会经常变化,而套餐却经常会变。
如果需要增加新的套餐,只需要在MealBuilder类中增加套餐即可。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。