建造者模式
- 建造者模式就是使用多个简单的对象, 一步一步建造合成, 零件加工, 最后成为一个满足需求的成品
- 就好比我们需要一个工厂首先加工出来的是螺丝和钢板, 最后将这个螺丝和钢板进行进一步的加工合成一个板凳, 这个过程就是一个建造者的模式, 将简单的对象, 一步一步加工合成一个满足需求的成品
- 主要解决: 主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
- 优点: 建造者是独立的, 解耦合, 易扩展, 便于控制细节
- 缺点: 产品必须有共同点(也就是有相同的零件), 如果内部变更, 会牵连到很多对象的修改(比如修改零件, 成品肯定都需要更改)
举例实现
- 当我们去一家肯德基店的时候, 菜单显示主食有蔬菜汉堡(vegBurger)和鸡肉汉堡(chiBurger), 饮品有可乐(Coke)和百事(Pepsi), 汉堡系列都是纸质包装(wrapper), 饮品系列都是瓶子包装(bottle), 而且他们都还有共同点都有名字(name)和价格(price), 最后我们发现还有蔬菜套餐蔬菜汉堡和可乐, 鸡肉套餐鸡肉汉堡和百事, 下面我用一个图展示零件和成品
public interface Packing {
public String pack();
}
public class Wrapper implements Packing {
@Override
public String pack() {
return "Wrapper";
}
}
public class Bottle implements Packing {
@Override
public String pack() {
return "Bottle";
}
}
public interface Item {
public String name();
public Packing pack();
public float price();
}
public abstract class Drink implements Item {
@Override
public abstract String name();
@Override
public Packing pack() {
return new Bottle();
}
@Override
public abstract float price();
}
public abstract class Burger implements Item {
@Override
public abstract String name();
@Override
public Packing pack() {
return new Wrapper();
}
@Override
public abstract float price();
}
public class VegBurger extends Burger {
@Override
public String name() {
return "VerBurger";
}
@Override
public float price() {
return (float) 13.14;
}
}
public class ChiBurger extends Burger {
@Override
public String name() {
return "ChiBurger";
}
@Override
public float price() {
return (float)52.50;
}
}
public class Pepsi extends Drink {
@Override
public String name() {
return "Pepsi Drink";
}
@Override
public float price() {
return (float)2.99;
}
}
public class Cock extends Drink {
@Override
public String name() {
return "Cock Drink";
}
@Override
public float price() {
return (float)3.21;
}
}
public interface Meal {
public void addItem(Item item);
public float getCost();
public void showItem();
}
public class MealModel implements Meal{
private List<Item> items = new ArrayList<>();
@Override
public void addItem(Item item) {
this.items.add(item);
}
@Override
public float getCost() {
float ret = 0;
for (Item item: items
) {
ret += item.price();
}
return ret;
}
@Override
public void showItem() {
for (Item item : items
) {
System.out.println(item.name() + ", " + item.pack().pack() + ", " + item.price());
}
}
}
public class Store {
public Meal getVegMeal() {
Meal meal = new MealModel();
meal.addItem(new VegBurger());
meal.addItem(new Cock());
return meal;
}
public Meal getChiMeal() {
Meal meal = new MealModel();
meal.addItem(new ChiBurger());
meal.addItem(new Pepsi());
return meal;
}
}
public class Demo {
public static void main(String[] args) {
Store store = new Store();
Meal vegMeal = store.getVegMeal();
System.out.println("show vegMeal");
vegMeal.showItem();
System.out.println("总价: " + vegMeal.getCost());
System.out.println();
Meal chiMeal = store.getChiMeal();
System.out.println("show chiMeal");
chiMeal.showItem();
System.out.println("总价: " + chiMeal.getCost());
}
}