Java 设计模式——建造者模式:从原理到实战的极简指南

Java 设计模式------建造者模式:从原理到实战的极简指南

建造者模式是一种实用的创建型设计模式,核心价值在于将对象的构建过程与对象本身分离。它能解决复杂对象创建时的参数混乱问题,让对象构建更灵活、更易读,是日常开发中必须掌握的基础模式。

文章目录

  • [Java 设计模式------建造者模式:从原理到实战的极简指南](#Java 设计模式——建造者模式:从原理到实战的极简指南)

一、核心原理:看透建造者模式的本质

1. 传统对象创建的痛点

在项目中,我们经常会遇到属性较多的类(如配置类、实体类)。以User类为例,传统全参构造函数的创建方式存在明显缺陷:

java 复制代码
@Data
public class User {
   private String username;
   private String email;
   private String phone;

   // 全参构造函数
   public User(String username, String email, String phone) {
       this.username = username;
       this.email = email;
       this.phone = phone;
   }
}
  • 参数可读性差 :创建对象时,需牢记参数顺序(如new User("钢铁侠", "``aa@gmail.com``", "111222333")),参数数量越多,越容易混淆含义;

  • 灵活性不足 :若只需给部分属性赋值(如仅设置邮箱和手机号),仍需为未使用的参数传null,代码冗余且易出错。

2. 建造者模式的解决方案

建造者模式通过引入 "建造者" 角色,将属性赋值过程拆分为独立步骤,同时支持链式调用,实现:

  1. 按需赋值:无需传入所有参数,仅设置需要的属性;

  2. 直观可读 :通过方法名明确属性含义(如.email("xxx")),无需查看构造函数定义;

  3. 构建解耦:对象的构建逻辑集中在建造者中,实体类仅负责存储数据。

二、适用场景

  1. 复杂对象创建:类的属性较多(通常超过 3 个),且需灵活组合不同属性;

  2. 配置类构建:框架配置、服务参数配置等场景(如数据库连接配置、HTTP 请求参数配置);

  3. 可读性优先场景:团队协作中,需让代码创建逻辑更直观,降低沟通成本。

三、实战案例:三种实现方式对比

1. 传统写法(反面案例)

测试类
java 复制代码
// 测试类
public class Test {
   public static void main(String[] args) {
       // 全参创建,参数顺序易混淆
       User user = new User("钢铁侠", "aa@gmail.com", "111222333");
       System.out.println(user);
   }
}
输出结果
text 复制代码
User(username=钢铁侠, email=aa@gmail.com, phone=111222333)
问题总结

如前文所述,该方式存在可读性差、灵活性不足的问题,不适合属性较多的类。

2. 手写建造者模式(基础实现)

通过手动编写建造者类,实现属性的链式赋值,核心是 "建造者持有目标对象,提供属性设置方法和构建方法"。

步骤 1:定义实体类
java 复制代码
package com.boke.desginpattern.builder.builder.entity;

import lombok.Data;

@Data
public class User {
   private String username;
   private String email;
   private String phone;

   // 提供静态方法获取建造者实例
   public static UserBuilder builder() {
       return new UserBuilder();
   }
}
步骤 2:定义建造者类
java 复制代码
package com.boke.desginpattern.builder.builder.entity;

public class UserBuilder {
   // 持有目标对象
   private final User user;

   // 建造者构造函数,初始化目标对象
   public UserBuilder() {
       this.user = new User();
   }

   // 逐个属性设置方法,返回建造者本身(支持链式调用)
   public UserBuilder username(String username) {
       user.setUsername(username);
       return this;
   }

   public UserBuilder email(String email) {
       user.setEmail(email);
       return this;
   }

   public UserBuilder phone(String phone) {
       user.setPhone(phone);
       return this;
   }

   // 构建方法,返回最终的目标对象
   public User build() {
       return user;
   }
}
步骤 3:测试代码
java 复制代码
package com.boke.desginpattern.builder.test;

import com.boke.desginpattern.builder.builder.entity.User;

public class Test {
   public static void main(String[] args) {
       // 链式调用,按需设置属性
       User user = User.builder()
               .email("aa@gmail.com")  // 明确设置邮箱
               .phone("111222333")    // 明确设置手机号
               .build();               // 构建对象
       System.out.println(user);
   }
}
输出结果
text 复制代码
User(username=null, email=aa@gmail.com, phone=111222333)
优势总结
  • 按需设置属性,无需传null

  • 方法名直观,代码可读性大幅提升;

  • 建造者与实体类分离,符合单一职责原则。

3. Lombok 自动生成建造者(推荐实战方式)

手动编写建造者类存在代码冗余问题,Lombok 的@Builder注解可自动生成建造者逻辑,无需手动编写重复代码。

步骤 1:定义实体类(添加@Builder注解)
java 复制代码
package com.boke.desginpattern.builder.lombok.entity;

import lombok.Builder;
import lombok.Data;

// @Builder 自动生成建造者逻辑
@Builder
@Data
public class User {
   private String username;
   private String email;
   private String phone;
}
步骤 2:测试代码
java 复制代码
package com.boke.desginpattern.builder.lombok.test;

import com.boke.desginpattern.builder.lombok.entity.User;

public class Test {
   public static void main(String[] args) {
       // 与手写建造者用法完全一致
       User user = User.builder()
               .username("钢铁侠")
               .email("aa@gmail.com")
               .build();
       System.out.println(user);
   }
}
输出结果
text 复制代码
User(username=钢铁侠, email=aa@gmail.com, phone=null)
优势总结
  • 零冗余代码:无需手动编写建造者类,简化开发流程;

  • 兼容性强:支持默认值、非空校验等扩展配置(需结合 Lombok 其他注解);

  • 符合开发习惯:生成的建造者用法与手写版本一致,学习成本低。

四、进阶技巧与注意事项

1. 进阶技巧

  • 属性校验 :在建造者的build()方法中添加属性校验逻辑(如邮箱格式校验、必填属性检查),确保对象创建的合法性:
java 复制代码
// 手写建造者的build方法增强
public User build() {
   if (user.getEmail() == null || !user.getEmail().contains("@")) {
       throw new IllegalArgumentException("邮箱格式非法");
   }
   return user;
}
  • Lombok 扩展配置 :结合@Builder.Default为属性设置默认值,结合@NonNull标记必填属性:
java 复制代码
@Builder
@Data
public class User {
   @NonNull // 标记为必填属性
   private String username;
   private String email;
   @Builder.Default // 设置默认值
   private String phone = "123456";
}

2. 注意事项

  • 避免过度使用 :若类的属性较少(≤3 个),直接使用构造函数或setter方法即可,无需引入建造者模式;

  • 线程安全问题:建造者类默认非线程安全,若在多线程环境中构建对象,需为属性设置方法添加同步锁;

  • Lombok 版本兼容 :部分旧版本 Lombok 的@Builder注解可能与其他注解(如@AllArgsConstructor)冲突,建议使用较新版本(1.18.20+)。

五、总结

建造者模式的核心是 "分离构建过程与对象本身",通过链式调用解决复杂对象创建的可读性和灵活性问题。日常开发中,推荐使用 Lombok 的@Builder注解快速实现建造者模式,提升开发效率;对于需要自定义构建逻辑(如属性校验、默认值设置)的场景,可手动编写建造者类。

掌握建造者模式,能让你的代码在处理复杂对象创建时更简洁、更易维护,尤其在团队协作和框架开发中,其价值更为突出。

相关推荐
工业甲酰苯胺3 小时前
实现 json path 来评估函数式解析器的损耗
java·前端·json
老前端的功夫3 小时前
Web应用的永生之术:PWA落地与实践深度指南
java·开发语言·前端·javascript·css·node.js
@forever@3 小时前
【JAVA】LinkedList与链表
java·python·链表
LilySesy3 小时前
ABAP+WHERE字段长度不一致报错解决
java·前端·javascript·bug·sap·abap·alv
六件套是我3 小时前
redission实现延时队列
android·java·servlet
王元_SmallA4 小时前
Redis Desktop Manager(Redis可视化工具)安装
java·后端
ᐇ9594 小时前
Java HashMap深度解析:数据结构、原理与实战指南
java·开发语言·数据结构
好好研究4 小时前
Spring框架 - 开发方式
java·后端·spring
武子康4 小时前
Java-166 Neo4j 安装与最小闭环 | 10 分钟跑通 + 远程访问 Docker neo4j.conf
java·数据库·sql·docker·系统架构·nosql·neo4j
2301_796512525 小时前
Rust编程学习 - 为什么说Cow 代表的是Copy-On-Write, 即“写时复制技术”,它是一种高效的 资源管理手段
java·学习·rust