类之间关系
 
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
总结:
可以很明显的看到,一个组装的过程,我们点一个蔬菜套餐,就要将蔬菜汉堡和可乐都加入到菜单中。建造者之所以称为建造者,就是因为建造是一个过程,因此这个模式更多的是关心这个最终的产品,是如何一步步形成的,而不是像我们之前学习的抽象工厂模式那样,直接返回一个产品。



京公网安备 11010502036488号