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注解快速实现建造者模式,提升开发效率;对于需要自定义构建逻辑(如属性校验、默认值设置)的场景,可手动编写建造者类。

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

相关推荐
zl97989914 小时前
SpringBoot-入门介绍
java·spring boot·spring
焰火199914 小时前
[Java]基于Redis的分布式环境下的自增编号生成器
java·后端
ZhengEnCi14 小时前
JPA-SQL 语句使用完全指南-自动生成vs手动编写的智能选择策略
java·spring boot·sql
毕设源码-钟学长15 小时前
【开题答辩全过程】以 菜谱分享平台为例,包含答辩的问题和答案
java·eclipse
可DRAK鸦|・ω・`)15 小时前
docker后端jar包本地构建镜像
java·docker·容器·jar
代码不停15 小时前
JavaEE初级——Thread多线程
java·jvm·java-ee
xxxxxxllllllshi15 小时前
Cookie、Session、JWT、SSO,网站与 APP 登录持久化与缓存
java·开发语言·jvm·数据结构·缓存·面试
郑重其事,鹏程万里15 小时前
commons-io
java
Tiny_React15 小时前
智能体设计模式-CH05:工具使用(Tool Use)
设计模式