建造者模式深度解析与实战应用

作者简介

我是摘星,一名全栈开发者,专注 Java后端开发、AI工程化 与 云计算架构 领域,擅长Python技术栈。热衷于探索前沿技术,包括大模型应用、云原生解决方案及自动化工具开发。日常深耕技术实践,乐于分享实战经验与学习心得,希望用通俗易懂的方式帮助开发者快速掌握核心技术。持续输出AI、云计算及开源技术相关内容,欢迎关注交流!

目录

作者简介

1. 技术背景

2. 概念定义

2.1 建造者模式定义

2.2 模式结构图解

3. 原理剖析

3.1 工作流程

3.2 设计原则体现

4. 技术实现

4.1 经典实现(汽车制造示例)

4.2 变体实现(链式调用版)

5. 应用场景

5.1 典型适用场景

5.2 行业应用分布

6. 实际案例

6.1 Java标准库应用

6.2 Spring框架中的BeanDefinitionBuilder

6.3 Lombok的@Builder实现

7. 优缺点分析

7.1 核心优势

7.2 潜在缺点

8. 纵横对比

8.1 建造者 vs 工厂模式

8.2 建造者 vs 抽象工厂

9. 实战思考

9.1 最佳实践建议

9.2 性能优化策略

10. 总结


1. 技术背景

在软件开发中,当遇到需要创建包含多个组成部分的复杂对象时(如HTML文档、汽车配置、订单系统等),传统构造方法面临三大痛点:

  1. 构造函数参数爆炸(Telescoping Constructor)
  2. 对象属性设置不完整(部分构造问题)
  3. 构造过程不可控(无法保证必填字段)

根据GitHub 2023年代码分析统计,建造者模式在以下场景使用率最高:

  • 配置对象构建(占比38%)
  • 文档生成系统(占比25%)
  • 游戏实体创建(占比18%)
  • 测试数据构造(占比12%)

2. 概念定义

2.1 建造者模式定义

建造者模式将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。其核心组件包括:

角色

职责说明

Director

控制构建过程的主管类

Builder

抽象构建接口

ConcreteBuilder

具体构建实现

Product

最终生成的复杂对象

2.2 模式结构图解

图1:建造者模式类图 - 展示主管、构建器与产品的协作关系

3. 原理剖析

3.1 工作流程

图2:建造者模式时序图 - 分步骤构建复杂对象的过程

3.2 设计原则体现

  1. 单一职责原则:将对象构造逻辑与业务逻辑分离
  2. 开闭原则:新增构建方式无需修改既有代码
  3. 控制反转:主管类统一管理构建流程

4. 技术实现

4.1 经典实现(汽车制造示例)

// 产品类  
class Car {  private String engine;  private int wheels;  private String color;  // 设置方法省略...  public void showSpecs() {  System.out.printf("Engine: %s, Wheels: %d, Color: %s\n",  engine, wheels, color);  }  
}  // 抽象建造者  
interface CarBuilder {  void buildEngine();  void buildWheels();  void paintColor();  Car getResult();  
}  // 具体建造者  
class SportsCarBuilder implements CarBuilder {  private Car car = new Car();  @Override  public void buildEngine() {  car.setEngine("V8 Twin-Turbo");  }  @Override  public void buildWheels() {  car.setWheels(4);  }  @Override  public void paintColor() {  car.setColor("Racing Red");  }  @Override  public Car getResult() {  return car;  }  
}  // 主管类  
class Mechanic {  public Car construct(CarBuilder builder) {  builder.buildEngine();  builder.buildWheels();  builder.paintColor();  return builder.getResult();  }  
}  // 客户端调用  
public class Client {  public static void main(String[] args) {  Mechanic mechanic = new Mechanic();  CarBuilder builder = new SportsCarBuilder();  Car myCar = mechanic.construct(builder);  myCar.showSpecs();  }  
}  

4.2 变体实现(链式调用版)

public class User {  private final String firstName;  // 必选  private final String lastName;   // 必选  private final int age;           // 可选  private final String phone;      // 可选  private User(UserBuilder builder) {  this.firstName = builder.firstName;  this.lastName = builder.lastName;  this.age = builder.age;  this.phone = builder.phone;  }  public static class UserBuilder {  private final String firstName;  private final String lastName;  private int age = 0;  private String phone = "";  public UserBuilder(String firstName, String lastName) {  this.firstName = firstName;  this.lastName = lastName;  }  public UserBuilder age(int age) {  this.age = age;  return this;  }  public UserBuilder phone(String phone) {  this.phone = phone;  return this;  }  public User build() {  // 验证必填字段  if (firstName == null || lastName == null) {  throw new IllegalStateException("必填字段缺失");  }  return new User(this);  }  }  
}  // 使用示例  
User user = new User.UserBuilder("张", "三")  .age(30)  .phone("13800138000")  .build();  

5. 应用场景

5.1 典型适用场景

  1. 需要生成的产品对象有复杂内部结构
    • XML/JSON文档生成
    • 邮件报文构造
  1. 产品对象的属性相互依赖
    • 电脑配置(CPU与主板兼容性检查)
    • 订单系统(商品库存验证)
  1. 需要隔离复杂对象的创建和使用
    • 游戏角色创建(装备、技能组合)
    • 测试数据构造

5.2 行业应用分布

图3:行业应用分布图 - 配置管理占据最大比例

6. 实际案例

6.1 Java标准库应用

// StringBuilder就是建造者模式的变体  
String html = new StringBuilder()  .append("<html>")  .append("<head><title>Builder Demo</title></head>")  .append("<body>")  .append("<h1>Hello World</h1>")  .append("</body>")  .append("</html>")  .toString();  

6.2 Spring框架中的BeanDefinitionBuilder

BeanDefinitionBuilder builder = BeanDefinitionBuilder  .rootBeanDefinition(MyService.class)  .addPropertyValue("host", "192.168.1.1")  .setInitMethodName("init")  .setScope(BeanDefinition.SCOPE_SINGLETON);  BeanDefinition beanDefinition = builder.getBeanDefinition();  

6.3 Lombok的@Builder实现

@Builder  
public class Order {  private String orderId;  private List<String> items;  private double totalPrice;  
}  // 自动生成建造者  
Order order = Order.builder()  .orderId("ORD-2023-001")  .items(Arrays.asList("Item1", "Item2"))  .totalPrice(99.99)  .build();  

7. 优缺点分析

7.1 核心优势

  1. 构造过程可控:可以精细化控制构建步骤
  2. 参数灵活组合:避免构造器参数爆炸问题
  3. 产品隔离:隐藏产品内部表示
  4. 构建复用:相同构建过程可创建不同产品

7.2 潜在缺点

  1. 代码复杂度增加:需要额外创建Builder类
  2. 性能开销:相比直接构造略有性能损失
  3. 适用范围有限:简单对象使用反而增加负担

图4:优缺点分析图

8. 纵横对比

8.1 建造者 vs 工厂模式

对比维度

建造者模式

工厂模式

构造目标

多部分组成的复杂对象

单个标准产品

构造过程

分步骤构造

一步构造完成

关注重点

对象的组装过程

对象的创建行为

适用场景

参数可选且组合复杂

固定结构的简单对象

8.2 建造者 vs 抽象工厂

对比维度

建造者模式

抽象工厂模式

产品数量

构建单个复杂对象

创建多个相关对象族

构造方式

分步骤渐进式构建

一次性创建完整产品族

核心目标

控制复杂对象的构造过程

保证产品族的兼容性

9. 实战思考

9.1 最佳实践建议

  1. 必选参数处理:通过Builder构造函数强制传入必选参数
  2. 参数验证时机:在build()方法中进行完整性校验
  3. 不可变对象:配合final字段创建线程安全对象
  4. 组合使用模式
// 建造者+原型模式  
public CarBuilder setPrototype(Car prototype) {  this.car = prototype.clone();  return this;  
}  

9.2 性能优化策略

  1. 对象池技术:对频繁创建的Builder实例进行池化
  2. 缓存构建结果:对相同参数的构建结果进行缓存
  3. 静态工厂方法:简化常用配置的构建过程
public static UserBuilder adminUser() {  return new UserBuilder("admin", "system")  .age(30)  .phone("10086");  
}  

10. 总结

建造者模式作为创建型设计模式的重要成员:

  1. 有效解决了复杂对象构造的参数组合与流程控制问题
  2. 通过分步构建机制,实现了构造过程与产品表示的分离
  3. 在JDK、Spring等主流框架中广泛应用,特别适合配置管理和文档生成场景
  4. 现代开发中常与Lombok等工具结合,大幅减少样板代码

随着领域驱动设计(DDD)的普及,建造者模式在值对象构建聚合根创建领域展现出新的价值。当系统需要处理具有复杂构造逻辑的业务对象时,它仍然是不可替代的解决方案。

权威参考:

  1. Effective Java - Item 2: Builder Pattern(Joshua Bloch经典论述)
  2. Builder Pattern in Spring Framework(官方文档)
  3. Lombok @Builder Annotation(自动化实现方案)
  4. Refactoring.Guru: Builder Pattern(模式详解与互动案例)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/pingmian/84444.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VScode - 我的常用插件01 - 主题插件Noctis

导言 Noctis 是一款为 Visual Studio Code 提供的主题插件&#xff0c;主打高对比度、护眼、美观。它有多种配色风格&#xff0c;适合不同的开发者审美和工作场景。 一、安装Noctis 二、设置颜色主题 三、测试主题 如上所示&#xff0c;有11种主题背景可以选择。这里&#xff…

【IQA技术专题】图像质量评价IQA技术和应用综述(万字长文!!)

专题介绍 图像质量评价&#xff08;Image Quality Assessment, IQA&#xff09;是图像处理、计算机视觉和多媒体通信等领域的关键技术之一。IQA不仅被用于学术研究&#xff0c;更在影像相关行业内实现了完整的商业化应用&#xff0c;涉及影视、智能手机、专业相机、安防监控、…

突然虚拟机磁盘只剩下几十K

第一步&#xff1a;查找哪些文件大于 100M find / -size 100M 第二步&#xff1a;删除掉无用的 log 发现&#xff0c;磁盘剩余空间并没有变大 假如一个文件正在被使用&#xff0c;你删除之后也是不会释放存储空间的。需要关闭相应的服务才能释放。

黑马教程强化day2-1

目录 一、Set集合1.Set集合特点2.Set集合分类3.hashSet底层原理&#xff1a;(基于哈希表存储数据的&#xff09;代码演示 5.hashSet集合元素的去重操作&#xff08;有些情况搞不动&#xff09;代码演示 6.LinkedHashSet的底层原理&#xff08;不常用&#xff0c;所以没有代码演…

【实习总结】C++ 通过pugi::xml库对xml文件进行操作

目录 相关背景 pugi::xml简概 将配置信息写入xml文件 读取xml文件中的配置信息 相关背景 当我们需要将某些配置信息写入项目目录下的xml文件&#xff0c;或者再程序启动时&#xff0c;加载项目下已有的的配置信息&#xff08;.xml&#xff09;&#xff0c;此时&#xff0c;我…

Linux文件回收机制:安全删除文件不怕误删

Linux文件回收机制&#xff1a;安全删除文件不怕误删 文章目录 Linux文件回收机制&#xff1a;安全删除文件不怕误删一、Linux默认没有“回收站”&#xff1f;二、打造你自己的Linux回收站1. 建立回收站目录2. 创建软删除命令remove3. 定时清理回收站4. 替换rm命令5. 完整脚本 …

数据结构排序

目录 1、插入排序 2、希尔排序 3、堆排序 4、直接选择排序 5、快排 6、归并排序 补&#xff1a;计数排序 1、插入排序 void InsertSort(int* arr, int n) {int i 0;for (int i 0; i 1 < n; i){int end i;int tmp arr[end 1];while (end > 0){if (arr[end] &…

Spring声明式事务生效是有条件滴!

在日常工作中&#xff0c;经常使用Transactional 注解进行事务的声明&#xff0c;但如果发现事务未生效&#xff0c;可以从下面几个方面进行排查。 常见失效场景总结 场景原因解决方案内部方法调用绕过了Spring代理注入自身或使用AopContextprivate方法AOP无法增强改为public方…

Code Composer Studio快捷键

文本编辑 编辑、查找、替换功能快捷键 功能快捷键撤销CutZ重做CutY剪切CtrlX复制CtrlC粘贴CtrlV删除Delete全选CtrlA代码块选中AltShiftA查找、替换Ctrl F查找下一个匹配的字符串CtrlK查找上一个匹配的字符串CtrlShiftK查看接口注释&#xff08;文档&#xff09;F2查看函数帮…

从认识AI开始-----生成对抗网络(GAN):通过博弈机制,引导生成

前言 生成对抗网络&#xff08;GAN&#xff09;是lan J. Goodfellow团队在2014年提出的生成架构&#xff0c; 该架构自诞生起&#xff0c;就产生了很多的话题&#xff0c;更是被称为生成对抗网络是“新世纪以来机器学习领域内最有趣的想法”。如今&#xff0c;基于生成对抗网络…

限流算法java实现

参考教程&#xff1a;2小时吃透4种分布式限流算法 1.计数器限流 public class CounterLimiter {// 开始时间private static long startTime System.currentTimeMillis();// 时间间隔&#xff0c;单位为msprivate long interval 1000L;// 限制访问次数private int limitCount…

Maven 构建性能优化深度剖析:原理、策略与实践

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

JS手写代码篇---手写深拷贝

17、深拷贝 深拷贝与浅拷贝最大的不同就是对象的属性是嵌套对象&#xff0c;会新建一个对象 步骤&#xff1a; 判断是否为对象判断是否为i数组或者对象&#xff0c;给新的有个容器遍历循环&#xff0c;如果是对象要遍历循环&#xff0c;采用递归 function deepCopy(obj){// …

【react实战】如何实现监听窗口大小变化

在日常开发场景中&#xff0c;监听窗口变化是一个比较常见又很重要的业务功能&#xff0c;其实实现起来也很简单&#xff0c;今天就来记录一下具体的实现以及注意事项。 实现思路 在 React 中&#xff0c;可以通过监听 window 的 resize 事件来检测可视区域&#xff08;viewp…

AVCap视频处理成帧和音频脚本

###############处理原视频&#xff0c;使其格式和原数据一样 import os import cv2 import subprocess import json from PIL import Image from pydub import AudioSegmentimport sys import shutil # &#x1f539; 第一步&#xff1a;强制检测并设置FFmpeg路径 &#x1f5…

数据冗余对企业运营的隐性成本

从客户管理到供应链优化&#xff0c;再到市场分析&#xff0c;数据无处不在&#xff0c;数据已成为企业运营的核心驱动力。然而&#xff0c;随着企业IT系统的多样化和数据量的激增&#xff0c;数据冗余&#xff08;Data Redundancy&#xff09;问题逐渐浮出水面&#xff0c;成为…

HTML原生日期插件增加周次显示

<div id="app" class="box box-info" style="border-top-color:white;"><!-- // 日期部分 --><div class="date-picker-container" style="position: relative; max-width: 200px;"><!-- 日期输入框 -…

渗透测试PortSwigger Labs:遭遇html编码和转义符的反射型XSS

1 处是我们输入的标签被服务器 html 编码后返回&#xff0c;被浏览器当作字符串显示出来&#xff0c;无法执行 javascript 2 处是唯一能控制的地方&#xff0c;正好在script标签范围内&#xff0c;可以尝试构造 依然存在转移单引号&#xff0c;我们输入转义符\让服务器添加的转…

Ansible 错误处理:确保高效自动化

当 Ansible 收到命令的非零返回码或模块故障时,默认情况下,它会停止在该主机上的执行,并在其他主机上继续执行。但是,在某些情况下,您可能需要不同的行为。有时非零返回码表示成功。有时您希望一台主机上的故障导致所有主机上的执行停止。Ansible 提供了处理这些情况的工具…

【无标题】NP完全问题的拓扑对偶统一解法 ——四色问题到P=NP的普适框架

NP完全问题的拓扑对偶统一解法 ——四色问题到PNP的普适框架 **摘要** 本文提出基于**拓扑膨胀-收缩对偶性**的计算理论框架&#xff0c;突破传统NP完全性理论局限。通过将离散组合问题转化为连续几何问题&#xff0c;并引入规范场量子求解机制&#xff0c;实现四色问题、子…