Java 设计模式——建造者模式:从原理到实战的极简指南
Java 设计模式——建造者模式:从原理到实战的极简指南
建造者模式是一种实用的创建型设计模式,核心价值在于将对象的构建过程与对象本身分离。它能解决复杂对象创建时的参数混乱问题,让对象构建更灵活、更易读,是日常开发中必须掌握的基础模式。
文章目录
- Java 设计模式——建造者模式:从原理到实战的极简指南
- 一、核心原理:看透建造者模式的本质
- 1. 传统对象创建的痛点
- 2. 建造者模式的解决方案
- 二、适用场景
- 三、实战案例:三种实现方式对比
- 1. 传统写法(反面案例)
- 测试类
- 输出结果
- 问题总结
- 2. 手写建造者模式(基础实现)
- 步骤 1:定义实体类
- 步骤 2:定义建造者类
- 步骤 3:测试代码
- 输出结果
- 优势总结
- 3. Lombok 自动生成建造者(推荐实战方式)
- 步骤 1:定义实体类(添加`@Builder`注解)
- 步骤 2:测试代码
- 输出结果
- 优势总结
- 四、进阶技巧与注意事项
- 1. 进阶技巧
- 2. 注意事项
- 五、总结
一、核心原理:看透建造者模式的本质
1. 传统对象创建的痛点
在项目中,我们经常会遇到属性较多的类(如配置类、实体类)。以User
类为例,传统全参构造函数的创建方式存在明显缺陷:
@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. 建造者模式的解决方案
建造者模式通过引入 “建造者” 角色,将属性赋值过程拆分为独立步骤,同时支持链式调用,实现:
-
按需赋值:无需传入所有参数,仅设置需要的属性;
-
直观可读:通过方法名明确属性含义(如
.email("xxx")
),无需查看构造函数定义; -
构建解耦:对象的构建逻辑集中在建造者中,实体类仅负责存储数据。
二、适用场景
-
复杂对象创建:类的属性较多(通常超过 3 个),且需灵活组合不同属性;
-
配置类构建:框架配置、服务参数配置等场景(如数据库连接配置、HTTP 请求参数配置);
-
可读性优先场景:团队协作中,需让代码创建逻辑更直观,降低沟通成本。
三、实战案例:三种实现方式对比
1. 传统写法(反面案例)
测试类
// 测试类
public class Test {public static void main(String[] args) {// 全参创建,参数顺序易混淆User user = new User("钢铁侠", "aa@gmail.com", "111222333");System.out.println(user);}
}
输出结果
User(username=钢铁侠, email=aa@gmail.com, phone=111222333)
问题总结
如前文所述,该方式存在可读性差、灵活性不足的问题,不适合属性较多的类。
2. 手写建造者模式(基础实现)
通过手动编写建造者类,实现属性的链式赋值,核心是 “建造者持有目标对象,提供属性设置方法和构建方法”。
步骤 1:定义实体类
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:定义建造者类
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:测试代码
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);}
}
输出结果
User(username=null, email=aa@gmail.com, phone=111222333)
优势总结
-
按需设置属性,无需传
null
; -
方法名直观,代码可读性大幅提升;
-
建造者与实体类分离,符合单一职责原则。
3. Lombok 自动生成建造者(推荐实战方式)
手动编写建造者类存在代码冗余问题,Lombok 的@Builder
注解可自动生成建造者逻辑,无需手动编写重复代码。
步骤 1:定义实体类(添加@Builder
注解)
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:测试代码
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);}
}
输出结果
User(username=钢铁侠, email=aa@gmail.com, phone=null)
优势总结
-
零冗余代码:无需手动编写建造者类,简化开发流程;
-
兼容性强:支持默认值、非空校验等扩展配置(需结合 Lombok 其他注解);
-
符合开发习惯:生成的建造者用法与手写版本一致,学习成本低。
四、进阶技巧与注意事项
1. 进阶技巧
- 属性校验:在建造者的
build()
方法中添加属性校验逻辑(如邮箱格式校验、必填属性检查),确保对象创建的合法性:
// 手写建造者的build方法增强
public User build() {if (user.getEmail() == null || !user.getEmail().contains("@")) {throw new IllegalArgumentException("邮箱格式非法");}return user;
}
- Lombok 扩展配置:结合
@Builder.Default
为属性设置默认值,结合@NonNull
标记必填属性:
@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
注解快速实现建造者模式,提升开发效率;对于需要自定义构建逻辑(如属性校验、默认值设置)的场景,可手动编写建造者类。
掌握建造者模式,能让你的代码在处理复杂对象创建时更简洁、更易维护,尤其在团队协作和框架开发中,其价值更为突出。