五.建造者模式

一.建造者模式的定义

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

二.核心结构

角色 职责
‌**产品 (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中设计模式干货,第一时间推送给你!
🔔 有什么问题也可以在评论区讨论🤝🤝🤝
相关推荐
paopaokaka_luck几秒前
基于Spring Boot+Vue的吉他社团系统设计和实现(协同过滤算法)
java·vue.js·spring boot·后端·spring
Warren982 小时前
Java Stream流的使用
java·开发语言·windows·spring boot·后端·python·硬件工程
架构师沉默3 小时前
Java优雅使用Spring Boot+MQTT推送与订阅
java·开发语言·spring boot
tuokuac3 小时前
MyBatis 与 Spring Boot版本匹配问题
java·spring boot·mybatis
zhysunny3 小时前
05.原型模式:从影分身术到细胞分裂的编程艺术
java·原型模式
草履虫建模4 小时前
RuoYi-Vue 项目 Docker 容器化部署 + DockerHub 上传全流程
java·前端·javascript·vue.js·spring boot·docker·dockerhub
皮皮林5514 小时前
强烈建议你不要再使用Date类了!!!
java
困鲲鲲5 小时前
设计模式:中介者模式 Mediator
设计模式·中介者模式
做一位快乐的码农5 小时前
基于Spring Boot和Vue电脑维修平台整合系统的设计与实现
java·struts·spring·tomcat·电脑·maven
77qqqiqi5 小时前
mp核心功能
java·数据库·微服务·mybatisplus