设计模式之建造者模式(创建型模式)
类之间关系
UML类图
流程解析
打包packing 有纸盒和瓶装两种。
菜单Item分两类,汉堡和冷饮。
汉堡分鸡肉和蔬菜。冷饮分牛奶和可乐。
现在我们要点餐,需要返回一个菜单的价格和餐品名字的详情。可以看到MealBuider类是最关键的。由于我们点的是一个菜单,需要多个产品。建造者会直接帮我们把菜单解决好,而不是我们自己去添加。
代码部分
两个核心接口
public interface Item {
public String name();
public Packing packing();
public int price();
}
public interface Packing {
public String pack();
}接口Packing的实现
public class Wrapper implements Packing {
@Override
public String pack() {
return "用盒子打包";
}
}
public class Bottle implements Packing {
@Override
public String pack() {
return "用瓶子装给我";
}
}接口Item的实现
两个抽象类
可以看到,Item的抽象类和Packing类有一个依赖关系。可以新建Packing接口的实现类
public abstract class Burger implements Item {
@Override
public Packing packing() {
return new Wrapper();
}
@Override
public abstract int price();
}
public abstract class ColdDrink implements Item {
@Override
public Packing packing() {
return new Bottle();
}
@Override
public abstract int price();
}4个具体实现类
public class Coke extends ColdDrink {
@Override
public int price() {
return 30;
}
@Override
public String name() {
return "可乐";
}
}
public class milk extends ColdDrink {
@Override
public int price() {
return 35;
}
@Override
public String name() {
return "牛奶";
}
}
public class VegBurger extends Burger {
@Override
public int price() {
return 25;
}
@Override
public String name() {
return "蔬菜憨包包";
}
}
public class ChickenBurger extends Burger {
@Override
public int price() {
return 50;
}
@Override
public String name() {
return "鸡肉憨包包";
}
}Meal类
这个类完成了价格的计算,以及最后的菜单打印功能。
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 int getCost(){
int cost = 0;
for (int i=0;i<items.size();i++) {
cost += items.get(i).price();
}
return cost;
}
public void showItems(){
for (int i=0;i<items.size();i++) {
System.out.print("Item : "+items.get(i).name());
System.out.print(", Packing : "+items.get(i).packing().pack());
System.out.println(", Price : "+items.get(i).price());
}
}
}MealBuilder 类
这个类完成了Meal类的建造,点餐的功能,即将菜品加入到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 milk());
return meal;
}
}Demo测试类
我们只需要知道,有一个点餐系统即MealBuilder,因此我们需要new一个这个类的对象,并且我们知道最终我们点的是一个菜单,因此Meal对象也是我们所知道的,但是不需要我们new,让MealBuider帮我们完成,正常来说,我们告诉他点一个蔬菜套餐,就能告诉我们详情,这里没有使用反射,因此是直接调用的mealBuilder.prepareVegMeal(),正常来说,我们告诉他要点一个蔬菜套餐,然后通过反射,然后取建立蔬菜菜单。
public class DemoMain {
public static void main(String[] args) {
MealBuilder mealBuilder = new MealBuilder();
Meal vegMeal = mealBuilder.prepareVegMeal();
System.out.println("素材套餐");
vegMeal.showItems();
System.out.println("总价格: " +vegMeal.getCost());
Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
System.out.println("荤菜套餐");
nonVegMeal.showItems();
System.out.println("总价格: " +nonVegMeal.getCost());
}
}运行结果
素材套餐 Item : 蔬菜憨包包, Packing : 用盒子打包, Price : 25 Item : 可乐, Packing : 用瓶子装给我, Price : 30 总价格: 55 荤菜套餐 Item : 鸡肉憨包包, Packing : 用盒子打包, Price : 50 Item : 牛奶, Packing : 用瓶子装给我, Price : 35 总价格: 85
总结:
可以很明显的看到,一个组装的过程,我们点一个蔬菜套餐,就要将蔬菜汉堡和可乐都加入到菜单中。建造者之所以称为建造者,就是因为建造是一个过程,因此这个模式更多的是关心这个最终的产品,是如何一步步形成的,而不是像我们之前学习的抽象工厂模式那样,直接返回一个产品。
初识设计模式 文章被收录于专栏
第一次学设计模式,学的不够透彻,但依旧有些心得值得做做笔记
