【设计模式笔记19】:建造者模式

文章目录

      • 建造者模式
        • [1. 模式动机](#1. 模式动机)
        • [2. 模式定义](#2. 模式定义)
        • [3. 结构及角色分析](#3. 结构及角色分析)
        • [4. 代码实现示例](#4. 代码实现示例)
        • [5. 模式评价与优点](#5. 模式评价与优点)
        • [6. 模式扩展](#6. 模式扩展)
          • [6.1 钩子方法](#6.1 钩子方法)
          • [6.2 抽象建造者组合产品 (简化结构)](#6.2 抽象建造者组合产品 (简化结构))

建造者模式

1. 模式动机
  • 现实场景: 设想我们要发送一封电子邮件。一封完整的邮件包含发件人地址、收件人地址、主题、正文、附件等多个部分。
  • 问题所在 :
    • 如果缺少了"收件人地址",这封邮件是无法发送的,它不是一个合格的"产品"。
    • 这些组成部分(属性)需要按照一定的规则或顺序组合起来,才能构成一个完整的对象。
  • 核心需求 : 在某些情况下,一个对象会有一些重要的属性。在这些属性没有被赋予恰当的值之前,该对象不能作为一个完整的、可使用的产品。我们需要一种方法,能够一步一步 地构建这个复杂对象 ,并保证构建过程的完整性和顺序性
2. 模式定义
  • 名称: 建造者模式 (Builder Pattern),又称为生成器模式。
  • 定义 : 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
  • 核心思想 :
    • 建造者模式是一步一步创建一个复杂对象的。
    • 它允许用户通过指定复杂对象的类型和内容 就可以构建它们,用户不需要知道内部的具体构建细节
  • 分类 : 属于对象创建型模式
3. 结构及角色分析

建造者模式的结构主要包含四个角色:

图片描述 :UML图展示了 Director 聚合了 BuilderBuilder 派生出 ConcreteBuilderConcreteBuilder 创建并依赖 Product

  • Product (产品角色)

    • 定义: 被构建的复杂对象,包含多个组成部件。
    • 职责: 具体建造者创建该产品的内部表示并定义它的装配过程。
  • Builder (抽象建造者)

    • 定义: 为创建一个 Product 对象的各个部件指定抽象接口。
    • 职责:
      1. 定义构建各个部件的抽象方法 (如 buildPartA(), buildPartB())。
      2. 定义返回最终产品的方法 (如 getResult())。
  • ConcreteBuilder (具体建造者)

    • 定义: 实现 Builder 接口。
    • 职责:
      1. 实现各个部件的具体构造和装配方法。
      2. 定义并明确它所创建的复杂表示。
      3. 提供一个方法返回创建好的产品 (getResult)。
  • Director (指挥者)

    • 地位 : 这是一个非常重要的类。
    • 职责:
      1. 隔离: 隔离了客户与对象的生产过程。
      2. 控制 : 负责控制产品的生成过程(顺序)。指挥者针对抽象建造者编程,客户端只需将具体的建造者注入给指挥者,指挥者就可以调用建造者的方法来生成产品。
4. 代码实现示例

以"套餐构建"的场景为例(Food 和 Drink)。

  • 指挥者类 (Director)
java 复制代码
class Director {
    // 聚合Builder对象
    private Builder builder;

    // 通过构造器注入具体的建造者
    public Director(Builder builder) {
        this.builder = builder;
    }

    // 构建(装配)方法:核心控制逻辑
    public Product construct(String food, String drink) {
        // 1. 构建食物
        builder.buildFood(food);
        // 2. 构建饮料
        builder.buildDrink(drink);
        // 3. 返回组装好的复杂产品
        return builder.buildProduct();
    }
}
  • 抽象建造者与具体建造者
java 复制代码
// 抽象建造者
abstract class Builder {
    public abstract void buildFood(String food);
    public abstract void buildDrink(String drink);
    public abstract Product buildProduct();
}

// 具体建造者
class ConcreteBuilder extends Builder {
    private Product product = new Product();

    @Override
    public void buildFood(String food) {
        product.setFood(food);
    }

    @Override
    public void buildDrink(String drink) {
        product.setDrink(drink);
    }

    @Override
    public Product buildProduct() {
        return product;
    }
}
5. 模式评价与优点
  1. 解耦 : 建造者模式将对象组件的单独建造 (由Builder负责)和装配(由Director负责)分离开来。
  2. 多态性 :
    • 不同的建造器,相同的装配逻辑 -> 可以建造出不同的对象
    • 相同的建造器,不同的装配顺序 -> 也可以建造出不同的对象
  3. 精细控制: 与工厂模式相比,建造者模式能更精细地控制产品的创建过程。
  4. 符合开闭原则: 增加新的具体建造者无须修改原有类库的代码。
6. 模式扩展

建造者模式在使用中有两个重要的扩展方向:

6.1 钩子方法
  • 目的: 为了更精细地控制产品的建造过程,比如某个部件是否需要构建。
  • 实现方式 :
    • 抽象建造者 中定义一个返回 boolean 类型的方法(通常命名为 isNeedXxx()),默认返回 truefalse
    • 具体建造者中重写该方法,根据实际情况返回。
    • 指挥者 (或构建逻辑)中,通过 if 判断该钩子方法的返回值,来决定是否执行某个构建步骤。
java 复制代码
// 抽象类中定义钩子方法
public boolean isNeedDrink() {
    return false; // 默认不需要
}

// 具体建造者中重写
@Override
public boolean isNeedDrink() {
    return true; // 这个套餐需要饮料
}

// 构建过程中使用
public Meal buildMeal() {
    // ...
    if (isNeedDrink()) {
        meal.setDrink(drink);
    }
    // ...
}
6.2 抽象建造者组合产品 (简化结构)
  • 目的 : 有时候为了简化代码,可以将 Product 对象的引用直接放在抽象建造者中,或者省略 Director 类直接在 Builder 中完成构建逻辑 。 如SpringAI框架中就有大量的Builder直接作为内部类执行构建,无需Director
  • 实现: 在抽象建造者中初始化产品对象,并提供 getter / build 方法。
相关推荐
syt_10132 小时前
设计模式之-享元模式
javascript·设计模式·享元模式
SUPER52665 小时前
本地开发环境_spring-ai项目启动异常
java·人工智能·spring
moxiaoran57535 小时前
Spring AOP开发的使用场景
java·后端·spring
小王师傅6610 小时前
【轻松入门SpringBoot】actuator健康检查(上)
java·spring boot·后端
醒过来摸鱼10 小时前
Java classloader
java·开发语言·python
专注于大数据技术栈10 小时前
java学习--StringBuilder
java·学习
锦瑟弦音10 小时前
微信小游戏分包(cocos自带分包)
笔记·游戏
loosenivy10 小时前
企业银行账户归属地查询接口如何用Java调用
java·企业银行账户归属地·企业账户查询接口·企业银行账户查询
IT 行者10 小时前
Spring Security 6.x 迁移到 7.0 的完整步骤
java·spring·oauth2