什么是建造者模式?
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
通俗一点说呢,我觉得就是把一些有共同点的实体,把相同点一层层剥开,一层层合并。那这个构建过程就属于建造实体,也就是建造者模式
图示
用一个生活中的案例,比如现在肯德基有几种菜品。蔬菜汉堡(Veg Burger)、鸡肉汉堡(Chicken Burger)、可口可乐(coke)、百世可乐(pepsi)。
首先,这四个菜品我们可以分为两种:汉堡(Burger)和饮品(drink),那么就可以把这个共同点抽出来,各自建一个父类。
这时候继续往深层次挖掘。这所有的菜品都需要包装呢,客人不可能直接用手拿着汉堡和饮料对吧。所以呢,我们可以把包装类也写出来。
好了,现在呢我们可以把菜品的共同属性合并起来,让他们实现同一个接口中的共同属性。
进行到这一步,我们基本把类构建完成了,下面就是如何使用的问题。
我们可以定义一个套餐类,里面有套餐合并的价格,可以传入不同菜品,并且把不同菜品打印出来
ok,这时候已经构建了基本的框架,因为使用不熟练,所以我们是通过实体类来反推接口的,那写代码的时候肯定要从上往下来一步步实现
实现
步骤 1
创建包装类的接口
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";
}
}
步骤 2
创建菜品的属性接口
public interface Item {
public String name();
public Packing packing();
public String price();
}
步骤3
/**
* 这是汉堡的父类,并且使用汉堡的包装
*/
public abstract class Burger implements Item{
@Override
public Packing packing() {
return new Wrapper();
}
}
/**
* 这是饮料的父类,并且使用饮料的瓶子包装
*/
public abstract class ColdDrink implements Item{
@Override
public Packing packing() {
return new Bottle();
}
}
步骤4
实现不同的菜品实体类,定义菜品名字和具体的价格
/**
* 这是鸡肉汉堡
*/
public class ChickenBurger extends Burger {
@Override
public String name() {
return "Chicken Burger";
}
@Override
public String price() {
return "35.0";
}
}
/**
* 这是蔬菜汉堡
*/
public class VegBurger extends Burger {
@Override
public String name() {
return "Veg Burger";
}
@Override
public String price() {
return "25.0";
}
}
/**
* 这是可口可乐
*/
public class Coke extends ColdDrink{
@Override
public String name() {
return "Coke";
}
@Override
public String price() {
return "5.0";
}
}
/**
* 这是百事可乐
*/
public class Pepsi extends ColdDrink {
@Override
public String name() {
return "Pepsi";
}
@Override
public String price() {
return "5.0";
}
}
步骤5
实现套餐类
public class Meal {
private List<Item> items = new ArrayList<>();
public void addItem(Item item){
items.add(item);
}
public String getCost(){
float cost = 0.0f;
for (Item item: items){
cost += Float.valueOf(item.price());
}
return String.valueOf(cost);
}
public void showItems(){
for (Item item: items){
System.out.print("Item :"+item.name());
System.out.print(", Packing :"+item.packing().pack());
System.out.println(", Price :"+item.price());
}
}
}
步骤6
定义套餐的具体菜品
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 Pepsi());
return meal;
}
}
步骤7
使用main方法来打印套餐内容,演示建造者模式
public class BuilderPatternDemo {
public static void main(String[] args) {
MealBuilder mealBuilder = new MealBuilder();
Meal mealVeg = mealBuilder.prepareVegMeal();
System.out.println("mealVeg");
mealVeg.showItems();
System.out.println("Total Cost: "+mealVeg.getCost());
Meal mealNonVeg = mealBuilder.prepareNonVegMeal();
System.out.println("mealNonVeg");
mealNonVeg.showItems();
System.out.println("Total Cost: "+mealNonVeg.getCost());
}
}
步骤8
输出结果
mealVeg
Item :Veg Burger, Packing :Wrapper, Price :25.0
Item :Coke, Packing :Bottle, Price :5.0
Total Cost: 30.0
mealNonVeg
Item :Chicken Burger, Packing :Wrapper, Price :35.0
Item :Pepsi, Packing :Bottle, Price :5.0
Total Cost: 40.0