简介
当类的构造器参数较多(尤其是包含大量可选参数)时,使用 Builder 模式 能更优雅。
三种模式创建多参数对象
重叠构造器模式
设要创建一个 User
类,包含以下参数:id
(必填)、username
(必填)、age
(可选)、email
(可选)、phone
(可选)。
举个例子 🌰
public class User {
private final int id;
private final String username;
private final int age;
private final String email;
private final String phone;
// 多个构造器导致代码冗余
public User(int id, String username) {
this(id, username, 0);
}
public User(int id, String username, int age) {
this(id, username, age, null);
}
public User(int id, String username, int age, String email) {
this(id, username, age, email, null);
}
public User(int id, String username, int age, String email, String phone) {
this.id = id;
this.username = username;
this.age = age;
this.email = email;
this.phone = phone;
}
}
重叠构造器模式的缺点❌
重叠构造器方式需要编写多个重载构造器,导致代码臃肿且难以维护。
JavaBean 模式
JavaBean模式(即无参构造器加setter方法)的特点是:提供无参构造器,通过 setter 方法设置属性。
举个例子 🌰
public class User {
private int id;
private String username;
private int age;
private String email;
private String phone;
// 无参构造器(强制存在)
public User() {}
// 通过 setter 方法设置属性
public void setId(int id) { this.id = id; }
public void setUsername(String username) { this.username = username; }
public void setAge(int age) { this.age = age; }
public void setEmail(String email) { this.email = email; }
public void setPhone(String phone) { this.phone = phone; }
}
使用 JavaBean 创建对象
User user = new User();
user.setId(007);
user.setUsername("Zhangsan");
user.setAge(25);
user.setEmail("zhangsan@gmail.com");
user.setPhone("123456789");
JavaBean 模式的缺点的缺点❌
1.需要多次调用 setter,代码冗长。
2.对象状态可能不一致:在调用所有 setter 方法之前,对象处于“未完全初始化”状态
3.无法实现不可变对象:JavaBean 依赖 setter 修改属性,导致对象状态可变,多线程环境下可能引发竞态条件。比如:一个线程正在设置 user.setAge(25)
,另一个线程可能同时调用 user.setAge(30)
,导致最终结果不确定。
Builder 模式
使用 Builder 模式 优雅地处理多参数构造问题。
举个例子 🌰
public class User {
private final int id;
private final String username;
private final int age;
private final String email;
private final String phone;
// 私有构造器,只能通过 Builder 创建实例
private User(Builder builder) {
this.id = builder.id;
this.username = builder.username;
this.age = builder.age;
this.email = builder.email;
this.phone = builder.phone;
}
// 静态内部 Builder 类
public static class Builder {
// 必填参数
private final int id;
private final String username;
// 可选参数(设置默认值)
private int age = 0;
private String email = null;
private String phone = null;
// 必填参数通过 Builder 构造器传入
public Builder(int id, String username) {
this.id = id;
this.username = username;
}
// 为每个可选参数提供链式方法
public Builder age(int age) {
this.age = age;
return this;
}
public Builder email(String email) {
this.email = email;
return this;
}
public Builder phone(String phone) {
this.phone = phone;
return this;
}
// 最终构建 User 对象
public User build() {
return new User(this);
}
}
}
使用 Builder 链式调用创建对象
User user = new User.Builder(1, "Zhangsan")
.age(25)
.email("zhangsan@gmail.com")
.phone("123456789")
.build();
Builder 模式的优点✅
1.灵活处理可选参数:不需要为每个参数组合编写多个构造器。
2.保证对象一致性:在 build() 方法中可添加参数校验逻辑,确保对象有效性。
3.线程安全:Builder 实例仅在当前线程使用,最终通过 build() 生成不可变对象。
总结
在需要处理多参数、必填参数、不可变对象或线程安全的场景下,Builder 模式 明显优于重叠构造器模式和 JavaBean 模式。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。