建造者模式(Builder Pattern)
建造者模式是一种 创建型设计模式,它将一个复杂对象的构造与它的表示分离,使得同样的构建过程可以创建不同的表示。
原理
- 核心思想:通过一步步的构建过程来创建复杂对象,而不是直接调用构造函数。
- 适用场景:需要创建的对象包含多个部分,且构造过程相对复杂时。
- 参与角色:
- Builder(抽象建造者):定义构建产品各部分的抽象接口。
- ConcreteBuilder(具体建造者):实现 Builder 接口,构造并装配具体的产品。
- Product(产品):要创建的复杂对象。
- Director(指挥者):定义构造步骤的顺序,将构建过程委托给建造者对象。
优点
- 分步构建:允许通过分步骤的方式构造对象,构造过程清晰。
- 易于扩展:可以灵活地创建不同的对象表示。
- 解耦构建过程与表示:更易维护和扩展。
缺点
- 复杂性增加:对于简单对象的创建会显得过于复杂。
- 依赖 Director:需要额外引入指挥者角色。
示例代码
场景描述
设计一个 MealBuilder 用于创建不同类型的套餐(如素食套餐和非素食套餐)。每个套餐包含主食(主菜)、饮料和甜品。
1. 定义产品类
// 产品类:Meal
public class Meal {
private String mainCourse;
private String drink;
private String dessert;
// Setter 方法
public void setMainCourse(String mainCourse) {
this.mainCourse = mainCourse;
}
public void setDrink(String drink) {
this.drink = drink;
}
public void setDessert(String dessert) {
this.dessert = dessert;
}
// 展示方法
public void showItems() {
System.out.println("Meal contains:");
System.out.println("Main Course: " + mainCourse);
System.out.println("Drink: " + drink);
System.out.println("Dessert: " + dessert);
}
}
2. 定义抽象建造者
// 抽象建造者
public abstract class MealBuilder {
protected Meal meal = new Meal();
public abstract void buildMainCourse();
public abstract void buildDrink();
public abstract void buildDessert();
// 返回构建好的产品
public Meal getMeal() {
return meal;
}
}
3. 定义具体建造者
// 具体建造者:素食套餐
public class VegMealBuilder extends MealBuilder {
@Override
public void buildMainCourse() {
meal.setMainCourse("Vegetable Curry");
}
@Override
public void buildDrink() {
meal.setDrink("Lemonade");
}
@Override
public void buildDessert() {
meal.setDessert("Fruit Salad");
}
}
// 具体建造者:非素食套餐
public class NonVegMealBuilder extends MealBuilder {
@Override
public void buildMainCourse() {
meal.setMainCourse("Chicken Curry");
}
@Override
public void buildDrink() {
meal.setDrink("Coke");
}
@Override
public void buildDessert() {
meal.setDessert("Ice Cream");
}
}
4. 定义指挥者
// 指挥者
public class MealDirector {
private MealBuilder builder;
public MealDirector(MealBuilder builder) {
this.builder = builder;
}
public Meal constructMeal() {
builder.buildMainCourse();
builder.buildDrink();
builder.buildDessert();
return builder.getMeal();
}
}
5. 客户端代码
public class BuilderPatternExample {
public static void main(String[] args) {
// 构建素食套餐
MealBuilder vegMealBuilder = new VegMealBuilder();
MealDirector vegDirector = new MealDirector(vegMealBuilder);
Meal vegMeal = vegDirector.constructMeal();
System.out.println("Veg Meal:");
vegMeal.showItems();
System.out.println("----------------------");
// 构建非素食套餐
MealBuilder nonVegMealBuilder = new NonVegMealBuilder();
MealDirector nonVegDirector = new MealDirector(nonVegMealBuilder);
Meal nonVegMeal = nonVegDirector.constructMeal();
System.out.println("Non-Veg Meal:");
nonVegMeal.showItems();
}
}
输出结果
Veg Meal:
Meal contains:
Main Course: Vegetable Curry
Drink: Lemonade
Dessert: Fruit Salad
----------------------
Non-Veg Meal:
Meal contains:
Main Course: Chicken Curry
Drink: Coke
Dessert: Ice Cream
UML 类图
+----------------+
| Meal |
+----------------+
| - mainCourse |
| - drink |
| - dessert |
+----------------+
| + setXXX() |
| + showItems() |
+----------------+
^
|
+----------------+
| MealBuilder |
+----------------+
| + buildXXX() |
| + getMeal() |
+----------------+
/ \
+---------------+ +-----------------+
| VegMealBuilder| | NonVegMealBuilder|
+---------------+ +-----------------+
^
|
+----------------+
| MealDirector |
+----------------+
| - builder |
| + constructMeal|
+----------------+
适用场景
- 复杂对象的创建:对象包含多个组成部分,且构建顺序不可或缺。
- 构造过程稳定,表示多样:同一构造流程可用于创建不同表示的对象。
- 代码清晰:通过分离构造过程简化了客户端逻辑。
小结
- 建造者模式适合构建复杂对象并关注构建过程的场景。
- 它将产品的创建与表示分离,提高了灵活性和扩展性。
- 缺点:当产品构造步骤或类型较少时,使用该模式可能显得冗余。