当前位置: 首页 > news >正文

设计模式(四)创建型:生成器模式详解

设计模式(四)创建型:生成器模式详解

生成器模式(Builder Pattern)是 GoF 23 种设计模式中的核心创建型模式之一,其核心价值在于将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。它特别适用于构造过程稳定但组成部分多变、配置参数繁杂的对象,如配置文件解析器、SQL 查询构造器、HTML 文档生成器、API 请求对象等。生成器模式通过分步构建对象并支持方法链式调用(Fluent Interface),极大提升了代码的可读性与可维护性。在现代框架中,该模式已演变为“流式 API”设计的基础,是构建复杂对象的优雅解决方案。

一、生成器模式详细介绍

生成器模式解决的是“复杂对象构造”中的常见痛点:当一个类的构造函数参数过多(尤其是存在大量可选参数)时,直接使用构造器或 setter 方法会导致代码冗长、易错且难以阅读。生成器模式通过引入一个独立的“生成器”对象,将对象的构建过程分解为多个清晰的步骤,最终通过 build() 方法一次性完成对象的创建。

该模式涉及以下关键角色:

  • Product(产品类):表示被构建的复杂对象。它通常具有多个组成部分或配置项,且构造过程较为复杂。该类的构造函数通常是私有的,防止外部直接实例化。
  • Builder(抽象生成器接口或抽象类):声明构建 Product 所需的各个构建步骤(如 setPartA()setPartB()),以及一个返回最终产品对象的 build() 方法。它定义了构建过程的契约。
  • ConcreteBuilder(具体生成器):实现 Builder 接口,负责具体地执行每一步构建操作,并维护一个 Product 实例的引用。它可以根据需要提供不同的构建逻辑,从而生成不同配置的 Product。
  • Director(指挥者,可选):负责调用 Builder 对象的各个构建方法,按照特定顺序执行构建流程。在许多现代实现中,Director 的职责被客户端直接承担,通过链式调用完成构建。

生成器模式的核心优势在于:

  • 解耦构建过程与表示:构建逻辑集中在 Builder 中,Product 类无需关心如何被创建。
  • 支持分步构建:允许逐步设置对象的各个部分,尤其适合依赖外部数据或条件判断的场景。
  • 实现不可变对象:Product 可以在构建完成后设为不可变(Immutable),提升线程安全性。
  • 支持方法链式调用:每个构建方法返回 this,实现流畅的 API 风格(Fluent API),如 builder.setA("a").setB("b").build()

与“工厂模式”相比,生成器更关注“如何构建”一个对象,而工厂关注“创建哪一个”对象。生成器适用于构建过程复杂、参数多变的场景,而工厂适用于类型选择明确的场景。

二、生成器模式的UML表示

以下是生成器模式的标准 UML 类图:

implements
creates
uses
constructed by
Product
-partA: String
-partB: int
-partC: boolean
+getPartA()
+getPartB()
+getPartC()
-Product(builder: Builder)
«abstract»
Builder
+setPartA(partA: String)
+setPartB(partB: int)
+setPartC(partC: boolean)
+build()
ConcreteBuilder
-partA: String
-partB: int
-partC: boolean
+setPartA(partA: String)
+setPartB(partB: int)
+setPartC(partC: boolean)
+build()
Director
-builder: Builder
+constructMinimal()
+constructFull()

图解说明

  • Product 是最终要构建的复杂对象,其构造函数为私有,只能通过 Builder 创建。
  • Builder 是抽象生成器,定义了设置各个部分的方法和 build() 方法。
  • ConcreteBuilder 实现 Builder,维护构建过程中的中间状态,并在 build() 中使用这些状态创建 Product
  • Director(可选)封装了标准的构建流程,如“最小构建”或“完整构建”。
  • 客户端可通过 ConcreteBuilder 链式调用设置参数,最后调用 build() 获取最终对象。

三、一个简单的Java程序实例

以下是一个基于生成器模式的 Java 示例,模拟构建一个 Email 对象:

// 产品类:Email
final class Email {private final String from;private final String to;private final String subject;private final String body;private final boolean isHtml;private final boolean isPriority;// 私有构造函数,只能通过 Builder 创建private Email(Builder builder) {this.from = builder.from;this.to = builder.to;this.subject = builder.subject;this.body = builder.body;this.isHtml = builder.isHtml;this.isPriority = builder.isPriority;}// Getter 方法public String getFrom() { return from; }public String getTo() { return to; }public String getSubject() { return subject; }public String getBody() { return body; }public boolean isHtml() { return isHtml; }public boolean isPriority() { return isPriority; }@Overridepublic String toString() {return "Email{" +"from='" + from + '\'' +", to='" + to + '\'' +", subject='" + subject + '\'' +", body='" + body + '\'' +", isHtml=" + isHtml +", isPriority=" + isPriority +'}';}// 静态内部生成器类public static class Builder {private String from;private String to;private String subject;private String body;private boolean isHtml = false;private boolean isPriority = false;public Builder from(String from) {this.from = from;return this; // 支持链式调用}public Builder to(String to) {this.to = to;return this;}public Builder subject(String subject) {this.subject = subject;return this;}public Builder body(String body) {this.body = body;return this;}public Builder html(boolean html) {this.isHtml = html;return this;}public Builder priority(boolean priority) {this.isPriority = priority;return this;}// 构建最终对象public Email build() {// 可在此处添加参数校验if (from == null || to == null || subject == null || body == null) {throw new IllegalStateException("Required fields (from, to, subject, body) must be set.");}return new Email(this);}}
}// 客户端使用示例
public class BuilderPatternDemo {public static void main(String[] args) {// 使用生成器构建一个普通邮件Email email1 = new Email.Builder().from("alice@example.com").to("bob@example.com").subject("Hello").body("This is a plain text email.").html(false).priority(false).build();System.out.println(email1);// 使用生成器构建一个高优先级 HTML 邮件Email email2 = new Email.Builder().from("admin@system.com").to("user@company.com").subject("Urgent: System Alert").body("<h1>CRITICAL ALERT!</h1><p>Server is down.</p>").html(true).priority(true).build();System.out.println(email2);}
}

运行说明

  • Email 类是不可变的,所有字段在构建后不可更改。
  • Builder 类提供链式方法设置各个字段,最后调用 build() 创建 Email 实例。
  • 客户端代码清晰、易读,避免了长参数列表或 setter 的繁琐调用。
  • build() 方法中可加入参数校验,确保对象的完整性。

四、总结

生成器模式通过引入独立的构建过程,成功解决了复杂对象构造的难题:

  • 提升可读性:链式调用使代码像自然语言一样流畅。
  • 支持可选参数:无需为不同参数组合定义多个构造函数(避免“伸缩构造器反模式”)。
  • 保证对象完整性:可在 build() 阶段集中校验参数,防止创建不合法对象。
  • 支持不可变性:Product 可设计为不可变对象,增强线程安全。

但也存在缺点:

  • 增加类复杂度:需要为每个复杂类定义一个 Builder。
  • 不适合简单对象:对于字段少、构造简单的类,使用 Builder 反而增加冗余。

因此,应在“对象复杂度”与“代码简洁性”之间权衡使用。

架构师洞见:
生成器模式是现代 API 设计的“黄金标准”。在 Spring、OkHttp、JPA Criteria API 等主流框架中,流式构建(Fluent Builder)已成为标配。架构师应认识到:生成器不仅是创建对象的工具,更是一种提升开发者体验(DX)的设计哲学。它通过“意图清晰的 API”降低使用门槛,减少错误。未来,随着 DSL(领域特定语言)和代码生成技术的发展,生成器将进一步自动化——通过注解处理器或 APT 自动生成 Builder 代码,消除样板代码。掌握生成器模式,有助于设计出既强大又易用的内部组件与公共 API,是构建高质量、可维护系统的关键能力。在微服务配置、消息构造、查询构建等高频场景中,生成器模式的价值尤为突出。

http://www.lryc.cn/news/601555.html

相关文章:

  • 第四科学范式(数据密集型科学):科学发现的新范式
  • NLP学习开始01-线性回归
  • 多租户Kubernetes集群架构设计实践——隔离、安全与弹性扩缩容
  • Vue基础(25)_组件与Vue的内置关系(原型链)
  • 马尔可夫链
  • MYSQL-- 行锁在索引命中与覆盖情况下的加锁行为
  • 随机密码生成
  • RTSP|RTMP播放器 in Unity:开源不够用?从工程视角重新定义播放器选型
  • Tkinter美化 - 告别土味Python GUI
  • 设计模式(二)创建型:工厂方法模式详解
  • 哈希表应用(map,set共同作用)
  • ubuntu18.04解压大的tar.gz文件失败
  • MySQL 全详解:从入门到精通的实战指南
  • vulhub-red靶机攻略
  • 优化Linux高并发:文件描述符与端口范围的协同调优
  • 【橘子分布式】gRPC(番外篇-客户端重试机制)
  • Python爬虫实战:研究tldextract库相关技术构建新闻网站域名分析爬虫系统
  • Java学习-------桥接模式
  • 3D芯片香港集成:技术突破与产业机遇全景分析
  • Python操作Excel文件完整指南
  • 依赖倒置原则 Dependency Inversion Principle - DIP
  • 2025 环法对决,VELO Angel Glide 坐垫轻装上阵
  • python优秀案例:基于python flask实现的小说文本数据分析与挖掘系统,包括K-means聚类算法和LDA主题分析
  • HBuilder X打包发布微信小程序
  • rust-包和箱子
  • 主要分布于内侧内嗅皮层的层Ⅲ的边界向量细胞(BVCs)对NLP中的深层语义分析的积极影响和启示
  • day062-监控告警方式与Grafana优雅展示
  • 【Oracle】套接字异常(SocketException)背后隐藏的Oracle问题:ORA-03137深度排查与解决之道
  • EasyExcel使用(二:写出)
  • MySQL 8.0.42创建MGR集群