建造者模式来实现制作儿童套餐的场景。假设儿童套餐包含以下组成部分:主食、饮料、玩具。不同的套餐组合可以有不同的主食、饮料和玩具。下面是一个具体的实现:
1. 定义产品类(儿童套餐)
public class KidsMeal {
private String mainCourse; // 主食
private String drink; // 饮料
private String toy; // 玩具
public void setMainCourse(String mainCourse) {
this.mainCourse = mainCourse;
}
public void setDrink(String drink) {
this.drink = drink;
}
public void setToy(String toy) {
this.toy = toy;
}
@Override
public String toString() {
return "KidsMeal{" +
"mainCourse='" + mainCourse + '\'' +
", drink='" + drink + '\'' +
", toy='" + toy + '\'' +
'}';
}
}
2. 定义抽象建造者类
public abstract class KidsMealBuilder {
protected KidsMeal kidsMeal;
public KidsMeal getKidsMeal() {
return kidsMeal;
}
public abstract void buildMainCourse();
public abstract void buildDrink();
public abstract void buildToy();
}
3. 实现具体建造者类
假设我们有两种套餐:套餐A和套餐B。
套餐A
public class MealABuilder extends KidsMealBuilder {
public MealABuilder() {
kidsMeal = new KidsMeal();
}
@Override
public void buildMainCourse() {
kidsMeal.setMainCourse("汉堡");
}
@Override
public void buildDrink() {
kidsMeal.setDrink("可乐");
}
@Override
public void buildToy() {
kidsMeal.setToy("小汽车");
}
}
套餐B
public class MealBBuilder extends KidsMealBuilder {
public MealBBuilder() {
kidsMeal = new KidsMeal();
}
@Override
public void buildMainCourse() {
kidsMeal.setMainCourse("鸡块");
}
@Override
public void buildDrink() {
kidsMeal.setDrink("果汁");
}
@Override
public void buildToy() {
kidsMeal.setToy("小飞机");
}
}
4. 定义指挥者类
public class Waiter {
private KidsMealBuilder kidsMealBuilder;
public void setKidsMealBuilder(KidsMealBuilder kidsMealBuilder) {
this.kidsMealBuilder = kidsMealBuilder;
}
public KidsMeal constructKidsMeal() {
kidsMealBuilder.buildMainCourse();
kidsMealBuilder.buildDrink();
kidsMealBuilder.buildToy();
return kidsMealBuilder.getKidsMeal();
}
}
5. 客户端代码
public class Main {
public static void main(String[] args) {
// 创建套餐A
KidsMealBuilder mealA = new MealABuilder();
Waiter waiter = new Waiter();
waiter.setKidsMealBuilder(mealA);
KidsMeal kidsMealA = waiter.constructKidsMeal();
System.out.println(kidsMealA);
// 创建套餐B
KidsMealBuilder mealB = new MealBBuilder();
waiter.setKidsMealBuilder(mealB);
KidsMeal kidsMealB = waiter.constructKidsMeal();
System.out.println(kidsMealB);
}
}
6. 输出结果
运行客户端代码,输出结果如下:
KidsMeal{mainCourse='汉堡', drink='可乐', toy='小汽车'}
KidsMeal{mainCourse='鸡块', drink='果汁', toy='小飞机'}
7. 优点
- 封装性好:将套餐的构建过程封装在具体的建造者类中,隐藏了构建细节。
- 易于扩展:新增套餐时,只需添加新的具体建造者类,无需修改现有代码。
- 便于控制细节:通过指挥者类,可以灵活地控制套餐的构建过程。
8. 适用场景
建造者模式适用于以下场景:
- 当需要构建一个复杂对象,且对象的构建过程复杂,包含多个步骤和多个部件时。
- 当需要隐藏对象的构建细节,只暴露一个简单的接口给客户端时。
- 当需要构建的对象有多种不同的表示时。
通过建造者模式,可以清晰地分离套餐的构建过程和表示,使得代码更加模块化、易于维护和扩展。
下面是一个使用建造者模式实现的儿童套餐制作系统 Python 程序。建造者模式非常适合这种需要分步构建复杂对象的场景,特别是当对象有多种配置选项时。
from abc import ABC, abstractmethod
# 产品:儿童套餐
class KidsMeal:
def __init__(self):
self.main_dish = None # 主餐
self.side_dish = None # 小食
self.drink = None # 饮料
self.toy = None # 玩具
def set_main_dish(self, main_dish):
self.main_dish = main_dish
def set_side_dish(self, side_dish):
self.side_dish = side_dish
def set_drink(self, drink):
self.drink = drink
def set_toy(self, toy):
self.toy = toy
def show_details(self):
print("\n儿童套餐详情:")
print(f"主餐:{self.main_dish}")
print(f"小食:{self.side_dish}")
print(f"饮料:{self.drink}")
print(f"玩具:{self.toy}")
print("=" * 30)
# 抽象建造者:套餐建造者
class MealBuilder(ABC):
@abstractmethod
def build_main_dish(self):
pass
@abstractmethod
def build_side_dish(self):
pass
@abstractmethod
def build_drink(self):
pass
@abstractmethod
def build_toy(self):
pass
@abstractmethod
def get_meal(self):
pass
# 具体建造者:快乐儿童餐建造者
class HappyMealBuilder(MealBuilder):
def __init__(self):
self.meal = KidsMeal()
def build_main_dish(self):
self.meal.set_main_dish("迷你汉堡")
def build_side_dish(self):
self.meal.set_side_dish("迷你薯条")
def build_drink(self):
self.meal.set_drink("苹果汁")
def build_toy(self):
self.meal.set_toy("卡通玩偶")
def get_meal(self):
return self.meal
# 具体建造者:超级儿童餐建造者
class SuperMealBuilder(MealBuilder):
def __init__(self):
self.meal = KidsMeal()
def build_main_dish(self):
self.meal.set_main_dish("小份炸鸡")
def build_side_dish(self):
self.meal.set_side_dish("玉米杯")
def build_drink(self):
self.meal.set_drink("橙汁")
def build_toy(self):
self.meal.set_toy("益智积木")
def get_meal(self):
return self.meal
# 指挥者:收银员
class Cashier:
def __init__(self, builder):
self.builder = builder
def construct_meal(self):
self.builder.build_main_dish()
self.builder.build_side_dish()
self.builder.build_drink()
self.builder.build_toy()
return self.builder.get_meal()
# 客户端代码
if __name__ == "__main__":
# 客户A想要一份快乐儿童餐
happy_builder = HappyMealBuilder()
cashier = Cashier(happy_builder)
happy_meal = cashier.construct_meal()
happy_meal.show_details()
# 客户B想要一份超级儿童餐
super_builder = SuperMealBuilder()
cashier.builder = super_builder # 更换建造者
super_meal = cashier.construct_meal()
super_meal.show_details()
# 客户C想要自定义套餐(扩展场景)
class CustomMealBuilder(MealBuilder):
def __init__(self):
self.meal = KidsMeal()
def build_main_dish(self):
self.meal.set_main_dish("儿童意面")
def build_side_dish(self):
self.meal.set_side_dish("蔬菜沙拉")
def build_drink(self):
self.meal.set_drink("牛奶")
def build_toy(self):
self.meal.set_toy("故事书")
def get_meal(self):
return self.meal
custom_builder = CustomMealBuilder()
cashier.builder = custom_builder # 再次更换建造者
custom_meal = cashier.construct_meal()
custom_meal.show_details()
这个实现中,我们定义了:
- 产品类(KidsMeal):表示儿童套餐,包含主餐、小食、饮料和玩具等组件。
- 抽象建造者(MealBuilder):定义了构建儿童套餐各个部分的接口。
- 具体建造者(HappyMealBuilder、SuperMealBuilder):实现了抽象建造者接口,构建不同类型的儿童套餐。
- 指挥者(Cashier):负责使用建造者构建套餐,控制构建过程的顺序。
通过这种设计,我们可以轻松地添加新的套餐类型(如示例中的 CustomMealBuilder),而不需要修改现有的代码结构。客户端只需要与指挥者和建造者接口交互,不需要了解具体的构建细节。
这个模式的优点在于将复杂对象的构建过程封装在具体建造者中,使得构建过程和表示分离,便于扩展和维护。