23种设计模式自我探索
建造者模式
建造者模式,使用多个简单的对象一步一步构建成一个复杂的对象
本次探索示例模拟美团、肯德基下单点餐打印订单信息
众所周知,咱们到麦当劳和肯德基点餐,最终目的是为了获取到对应食物
本例中食物Meal作为最终输出对象
食物包含名字,包装,金额等信息,不同种类的食物(蔬菜和肉类)继承食物种类(吃的和喝的),而吃的和喝的实现总接口Item
通过继承和实现,最终每个食物都属于Item,输出Item列表,即展示了食物列表
闲话少说,直接上代码
package com.ttjb.demo.model.builder;
public interface Item {
public String name();
public Packing packing();
public float price();
}
package com.ttjb.demo.model.builder;
public interface Packing {
public String pack();
}
吃的和喝的进行包装时,分别可以通过包装盒和瓶子(杯子也行)进行包装,这时候只需要通过两个Packing的实现类进行包装方式的区分即可
package com.ttjb.demo.model.builder.packing;
import com.ttjb.demo.model.builder.Packing;
public class Bottle implements Packing {
@Override
public String pack() {
return "Bottle";
}
}
package com.ttjb.demo.model.builder.packing;
import com.ttjb.demo.model.builder.Packing;
public class Wrapper implements Packing {
@Override
public String pack() {
return "Wrapper";
}
}
吃的和喝的都属于Item,作为商品都应该具有name,packing和price等属性,所以需要实现Item接口
package com.ttjb.demo.model.builder.goods.type;
import com.ttjb.demo.model.builder.Item;
import com.ttjb.demo.model.builder.Packing;
import com.ttjb.demo.model.builder.packing.Wrapper;
public abstract class Burger implements Item {
@Override
public Packing packing() {
return new Wrapper();
}
@Override
public abstract float price();
}
package com.ttjb.demo.model.builder.goods.type;
import com.ttjb.demo.model.builder.packing.Bottle;
import com.ttjb.demo.model.builder.Item;
import com.ttjb.demo.model.builder.Packing;
public abstract class ColdDrink implements Item {
@Override
public Packing packing() {
return new Bottle();
}
@Override
public abstract float price();
}
而吃的和喝的可以细分具体的食物和饮料,这里以炸鸡🐔、汉堡🍔、橙汁🍊和可乐作为示例
package com.ttjb.demo.model.builder.goods;
import com.ttjb.demo.model.builder.goods.type.Burger;
public class FriedChicken extends Burger {
@Override
public String name() {
return "Fried Chicken";
}
@Override
public float price() {
return 30.0f;
}
}
package com.ttjb.demo.model.builder.goods;
import com.ttjb.demo.model.builder.goods.type.Burger;
public class Hamburger extends Burger {
@Override
public String name() {
return "Hamburger";
}
@Override
public float price() {
return 15.0f;
}
}
package com.ttjb.demo.model.builder.goods;
import com.ttjb.demo.model.builder.goods.type.ColdDrink;
public class Orange extends ColdDrink {
@Override
public String name() {
return "Orange";
}
@Override
public float price() {
return 3.0f;
}
}
package com.ttjb.demo.model.builder.goods;
import com.ttjb.demo.model.builder.goods.type.ColdDrink;
public class Coke extends ColdDrink {
@Override
public String name() {
return "Coke";
}
@Override
public float price() {
return 20.0f;
}
}
准备工作做完之后,开始构造最终输出对象Meal,需要包含价格和相关食物条目信息
package com.ttjb.demo.model.builder.meals;
import com.ttjb.demo.model.builder.Item;
import java.util.ArrayList;
import java.util.List;
public class Meal {
private List<Item> itemList = new ArrayList<>();
public void addItem(Item item) {
itemList.add(item);
}
public float getCost() {
float cost = 0.0f;
for (Item item : itemList) {
cost += item.price();
}
return cost;
}
public void showItems() {
for (Item item : itemList) {
System.out.print("Item : " + item.name());
System.out.print(", Packing : " + item.packing().pack());
System.out.println(", Price : " + item.price());
}
}
}
开始造食物
package com.ttjb.demo.model.builder.meals;
import com.ttjb.demo.model.builder.Item;
public class MealBuilderWithParam {
public Meal prepareVegMeal(Item... item) {
Meal meal = new Meal();
for (int i = 0; i < item.length; i++) {
meal.addItem(item[i]);
}
return meal;
}
public Meal prepareNonVegMeal(Item... item) {
Meal meal = new Meal();
for (int i = 0; i < item.length; i++) {
meal.addItem(item[i]);
}
return meal;
}
}
测试代码,打印订单信息
package com.ttjb.demo.model.builder;
import com.ttjb.demo.model.builder.goods.*;
import com.ttjb.demo.model.builder.meals.Meal;
import com.ttjb.demo.model.builder.meals.MealBuilder;
import com.ttjb.demo.model.builder.meals.MealBuilderWithParam;
/**
* 建造者模式
* 使用多个简单的对象一步一步构建成一个复杂的对象
* 食物Meal作为最终输出对象
* 食物包含名字,包装,金额,不同种类的食物(蔬菜和肉类)继承食物种类(吃的和喝的),而吃的和喝的实现总接口Item
* 通过继承和实现,最终每个食物都属于Item,输出Item列表,即展示了食物列表
*/
public class TestBuilderModelWithParam {
public static void main(String[] args) {
MealBuilderWithParam mealBuilder = new MealBuilderWithParam();
System.out.println("=========================================");
Meal vegMeal = mealBuilder.prepareVegMeal(new Orange(), new Hamburger(), new Coke());
System.out.println("Veg Meal");
vegMeal.showItems();
System.out.println("Total Cost: " + vegMeal.getCost());
System.out.println("=========================================");
Meal nonVegMeal = mealBuilder.prepareNonVegMeal(new FriedChicken(), new Coke());
System.out.println("Non-Veg Meal");
nonVegMeal.showItems();
System.out.println("Total Cost: " + nonVegMeal.getCost());
System.out.println("=========================================");
Meal drink = mealBuilder.prepareNonVegMeal(new Coke());
System.out.println("Drink Meal");
drink.showItems();
System.out.println("Total Cost: " + drink.getCost());
}
}
输出结果
=========================================
Veg Meal
Item : Orange, Packing : Bottle, Price : 3.0
Item : Hamburger, Packing : Wrapper, Price : 15.0
Item : Coke, Packing : Bottle, Price : 20.0
Total Cost: 38.0
=========================================
Non-Veg Meal
Item : Fried Chicken, Packing : Wrapper, Price : 30.0
Item : Coke, Packing : Bottle, Price : 20.0
Total Cost: 50.0
=========================================
Drink Meal
Item : Coke, Packing : Bottle, Price : 20.0
Total Cost: 20.0
参考文献:https://www.runoob.com/design-pattern/builder-pattern.html
虽然说也是从其他博客上学习的,但是加入了自己的理解,仅以此文铭记,供大大们参考