五.建造者模式

一.建造者模式的定义

建造者模式是一种对象构建的设计模式,它将一个复杂对象的构建过程与其表示分离,使得同样的构建逻辑可以创建不同的表示。这种模式适用于那些构建过程复杂、步骤多变的对象,尤其是当对象的创建涉及多个可选参数时。

二.核心结构

角色 职责
‌**产品 (Product)**‌ 最终构建的复杂对象,包含多个部件
‌**抽象建造者 (Builder)**‌ 定义构建产品部件的抽象接口
‌**具体建造者 (ConcreteBuilder)**‌ 实现抽象建造者接口,完成部件的具体构造与装配
‌**指挥者 (Director)**‌ 控制构建流程,按固定顺序调用建造者方法

想象你在 搭乐高积木:

  • 你想搭一辆车,这辆车有很多部分:轮子、发动机、车门、颜色等等。
  • 搭建这辆车的过程(比如先装底盘、再装引擎、然后喷漆)是固定的,但每个部分你可以选择不同的样式:
    • 有人要跑车款(红色、运动轮胎)
    • 有人要越野款(绿色、大轮胎)
    • 有人要电动车(白色、无引擎)
  • 建造者模式就是帮你:
  • 把组装流程标准化(先装底盘 → 再装轮子 → 最后喷漆),不管你要哪种车。
  • 让不同"建造者"负责不同款式(跑车建造者、越野车建造者)。
  • 最后你只要告诉指挥者:"按这个建造者的风格来搭",就能得到你想要的那辆车(产品)。

建造者模式适用于:构建一个复杂的对象,其构建步骤是固定的,但每一步的具体实现可以不同。

三.案例

3.1.产品

java 复制代码
/**
 * 产品类:Meal
 * 表示一个完整的套餐对象,包含多个项目(如主食、饮料、附加品等)。
 * 在本案例中,用于模拟餐厅点餐系统中的套餐构建过程。
 */
public class Meal {
    private List<String> items = new ArrayList<>();

    /**
     * 添加一项到套餐中
     * @param item 要添加的物品名称
     */
    public void addItem(String item) {
        items.add(item);
    }

    /**
     * 显示套餐中的所有项目
     */
    public void showItems() {
        for (String item : items) {
            System.out.println("Item: " + item);
        }
    }

    /**
     * 获取套餐总价格
     * @return 套餐总价(简化为每项10元)
     */
    public double getCost() {
        return items.size() * 10.0;
    }
}

3.2.抽象建造者

java 复制代码
/**
 * 抽象建造者
 * 定义了构建套餐对象的通用步骤。
 * 所有具体构建者类都必须实现这些方法来提供具体的构建逻辑。
 */
public interface MealBuilder {
    /**
     * 构建主食
     */
    void buildMainCourse();

    /**
     * 构建饮料
     */
    void buildDrink();

    /**
     * 构建甜点或附加品
     */
    void buildDessert();

    /**
     * 获取构建完成的套餐对象
     * @return 构建好的 Meal 对象
     */
    Meal getMeal();
}

3.3.具体构建者

java 复制代码
/**
 * 具体构建者:FamilyMealBuilder
 * 实现家庭套餐的构建过程。
 * 提供具体的构建步骤,如主食、饮料和附加品。
 */
public class FamilyMealBuilder implements MealBuilder {
    private Meal meal;

    public FamilyMealBuilder() {
        this.meal = new Meal();
    }

    /**
     * 构建家庭套餐的主食:炸鸡
     */
    @Override
    public void buildMainCourse() {
        meal.addItem("炸鸡");
    }

    /**
     * 构建家庭套餐的饮料:两杯可乐
     */
    @Override
    public void buildDrink() {
        meal.addItem("两杯可乐");
    }

    /**
     * 构建家庭套餐的附加品:薯条和沙拉
     */
    @Override
    public void buildDessert() {
        meal.addItem("薯条");
        meal.addItem("沙拉");
    }

    /**
     * 获取构建完成的家庭套餐
     * @return 构建好的 Meal 对象
     */
    @Override
    public Meal getMeal() {
        return meal;
    }
}

/**
 * 具体构建者:KidsMealBuilder
 * 实现儿童套餐的构建过程。
 * 提供具体的构建步骤,如主食、饮料和附加品。
 */
public class KidsMealBuilder implements MealBuilder {
    private Meal meal;

    public KidsMealBuilder() {
        this.meal = new Meal();
    }

    /**
     * 构建儿童套餐的主食:汉堡
     */
    @Override
    public void buildMainCourse() {
        meal.addItem("汉堡");
    }

    /**
     * 构建儿童套餐的饮料:可乐
     */
    @Override
    public void buildDrink() {
        meal.addItem("可乐");
    }

    /**
     * 构建儿童套餐的附加品:小玩具
     */
    @Override
    public void buildDessert() {
        meal.addItem("小玩具");
    }

    /**
     * 获取构建完成的儿童套餐
     * @return 构建好的 Meal 对象
     */
    @Override
    public Meal getMeal() {
        return meal;
    }
}

3.4.指挥者

java 复制代码
/**
 * 指挥者类:Waiter
 * 负责控制构建流程,调用构建者的各个步骤来完成套餐的构建。
 * 该类不关心具体构建细节,只负责执行构建顺序。
 */
public class Waiter {
    private MealBuilder mealBuilder;

    /**
     * 设置当前使用的构建者
     * @param mealBuilder 构建者对象
     */
    public void setMealBuilder(MealBuilder mealBuilder) {
        this.mealBuilder = mealBuilder;
    }

    /**
     * 执行构建流程
     * @return 构建完成的套餐对象
     */
    public Meal constructMeal() {
        mealBuilder.buildMainCourse();
        mealBuilder.buildDrink();
        mealBuilder.buildDessert();
        return mealBuilder.getMeal();
    }
}

3.5.客户端调用

创建指挥者对象,传入构建者,获得产品。

java 复制代码
/**
 * 测试入口类:RestaurantDemo
 * 模拟餐厅点餐系统的使用场景,通过建造者模式构建不同类型的套餐。
 */
public class RestaurantDemo {
    public static void main(String[] args) {
        // 创建指挥者
        Waiter waiter = new Waiter();

        // 构建儿童套餐
        MealBuilder kidsMealBuilder = new KidsMealBuilder();
        waiter.setMealBuilder(kidsMealBuilder);
        Meal kidsMeal = waiter.constructMeal();

        System.out.println("儿童套餐:");
        kidsMeal.showItems();
        System.out.println("总价: ¥" + kidsMeal.getCost());

        // 构建家庭套餐
        MealBuilder familyMealBuilder = new FamilyMealBuilder();
        waiter.setMealBuilder(familyMealBuilder);
        Meal familyMeal = waiter.constructMeal();

        System.out.println("\n家庭套餐:");
        familyMeal.showItems();
        System.out.println("总价: ¥" + familyMeal.getCost());
    }
}

四.应用场景

4.1. 餐厅点餐系统

构建流程统一(先主食 → 再饮料 → 后甜点)。

4.2.游戏角色创建系统

角色创建流程一致(设置基础属性 → 添加装备 → 设置技能)

4.3. 文档生成器(PDF、Word、HTML)

文档生成步骤一致(设置标题 → 添加正文 → 插入页脚)

java 复制代码
💡 如果本文对你有帮助,点击右上角【订阅专栏】或左上角关注我  
🔔 完整的23中设计模式干货,第一时间推送给你!
🔔 有什么问题也可以在评论区讨论🤝🤝🤝
相关推荐
小信丶7 分钟前
Spring Cloud Stream EnableBinding注解详解:定义、应用场景与示例代码
java·spring boot·后端·spring
无限进步_11 分钟前
【C++】验证回文字符串:高效算法详解与优化
java·开发语言·c++·git·算法·github·visual studio
亚历克斯神12 分钟前
Spring Cloud 2026 架构演进
java·spring·微服务
七夜zippoe15 分钟前
Spring Cloud与Dubbo架构哲学对决
java·spring cloud·架构·dubbo·配置中心
海派程序猿15 分钟前
Spring Cloud Config拉取配置过慢导致服务启动延迟的优化技巧
java
阿维的博客日记26 分钟前
为什么不逃逸代表不需要锁,JIT会直接删掉锁
java
William Dawson27 分钟前
CAS的底层实现
java
九英里路39 分钟前
cpp容器——string模拟实现
java·前端·数据结构·c++·算法·容器·字符串
YDS82943 分钟前
大营销平台 —— 抽奖前置规则过滤
java·spring boot·ddd
仍然.1 小时前
多线程---CAS,JUC组件和线程安全的集合类
java·开发语言