构造者(builder)设计模式是通过将复杂对象的构造过程拆分为多个简单的步骤,使得创建对象更加灵活,可读性和可维护性更强。
什么是构造者模式
Java 构造(造)者(builder)设计模式将复杂对象的创建过程分解成多个简单的构造步骤,提供了一种优雅的方式来构造特定类型的对象。通常情况下,在创建对象时,需要处理很多参数或者属性。如果使用传统的工厂模式,则需要编写很多的构造函数。这样的代码可读性差,维护成本也高。而使用构造者(builder)模式,则可以更好的解决这个问题。构造者(builder)模式将复杂对象的创建过程分解成多个简单的构造步骤,并提供了自定义序列的构造方法,程序员可以根据需要自定义构造步骤及它们的顺序,从而使创建复杂对象更加优雅、灵活与可管理。
构造者模式的使用场景
- 创建对象时包含多个属性或字段。
- 需要创建不可变对象(对象初始化时一旦设置,就不能修改属性变量)。
- 需要在对象创建过程中根据不同条件创建不同类型的对象。
构造者模式的代码示例:
Person 类:
// 定义一个 Person 类
public class Person {
private final String firstName; // 必选项,用 final 修饰
private final String lastName; // 必选项,用 final 修饰
private final int age; // 可选项,不用 final 修饰
private final String phoneNumber; // 可选项,不用 final 修饰
// Person 的构造函数私有化
private Person(Builder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.phoneNumber = builder.phoneNumber;
}
// 建造器类
public static class Builder {
private final String firstName; // 必选项,用 final 修饰
private final String lastName; // 必选项,用 final 修饰
private int age; // 可选项,不用 final 修饰
private String phoneNumber; // 可选项,不用 final 修饰
public Builder(String firstName, String lastName) { // 必选参数
this.firstName = firstName;
this.lastName = lastName;
}
public Builder age(int age) { // 可选参数
this.age = age;
return this;
}
public Builder phoneNumber(String phoneNumber) { // 可选参数
this.phoneNumber = phoneNumber;
return this;
}
// 构造 Person 对象并返回
public Person build() {
return new Person(this);
}
}
// Person 类的其它方法
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public String getPhoneNumber() {
return phoneNumber;
}
@Override
public String toString() {
return "Person{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", age=" + age +
", phoneNumber='" + phoneNumber + '\'' +
'}';
}
}
Person 类中有一个私有化的构造函数,以及一个建造器类 Builder。Builder 类中没有所有属性的构造函数和 setter 方法,而是在 build() 函数中返回一个 Person 对象,并将它的属性设置为之前在 Builder 中设置的属性。
现在,让我们使用Builder 模式来创建一个 Person:
public class BuilderExample {
public static void main(String[] args) {
// 创建一个 Person 对象,只设置了必选项
Person person1 = new Person.Builder("John", "Doe").build();
System.out.println(person1); // 输出:Person{firstName='John', lastName='Doe', age=0, phoneNumber='null'}
// 创建一个 Person 对象,设置了所有选项
Person person2 = new Person.Builder("Jane", "Doe")
.age(25)
.phoneNumber("555-555-5555")
.build();
System.out.println(person2); // 输出:Person{firstName='Jane', lastName='Doe', age=25, phoneNumber='555-555-5555'}
}
}
在上面的代码示例中,我们创建了两个 Person 对象。一个只设置了必选项,另一个则设置了所有选项。使用Builder 模式可以使得对象创建过程更加容易和可管理。
构造者模式的实际应用
在实际的 Spring Boot 开发中,有很多常用框架广泛使用了 Builder 模式,以下是一些常用的框架及其使用 Builder 模式的示例:
- Spring Security
Spring Security 使用了建造者模式,在多个链式方法中配置和定制身份验证和安全性选项。以下是创建一个简单的 Spring Security 配置的示例:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/index/**").hasRole("USER") //筛选请求
.and()
.formLogin();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
- Lombok
Lombok 是一个非常流行的 Java 库,它通过提供注释来简化代码,其中也包括带有 Builder 模式支持的 @Builder 注释。以下是一个使用 Lombok 和 Builder 模式的例子:
@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class User {
private final String firstName;
private final String lastName;
private final int age;
private final String email;
// getters
}
- Google Guava
Google Guava 是一个功能强大的 Java 库,它包含了很多方便的工具和函数,其中也包括了一个使用 Builder 模式来创建不可变对象的 API。以下是一个使用 Google Guava 的不可变对象及 Builder 模式的示例:
ImmutableList<String> list = ImmutableList.<String>builder()
.add("USA")
.add("India")
.add("China")
.add("Russia")
.add("Japan")
.build();
System.out.println(list);
- Retrofit
Retrofit 是一个非常流行的 Android 和 Java 网络库,它使用 Builder 模式来构造 Rest API 调用。以下是如何使用 Retrofit API 创建一个请求的示例:
Call<List<User>> call = apIService.GetUser(id).execute();
总结
构造者模式是一种创建型设计模式,它可以用于创建复杂对象。它提供了一种更优雅和可读性更高的方式来创建对象,而不是通过多个构造函数或方法来创建对象。
构造者模式的核心思想是将一个复杂的对象的构建与表示分离开来,以便同样的构建过程可以创建不同的表示。这种分离可以使构建过程更加灵活,并使客户端代码更加简单,不需要关心对象的构建细节。
关注微信公众号:“小虎哥的技术博客”。我们会定期发布关于Java技术的详尽文章,让您能够深入了解该领域的各种技巧和方法,让我们一起成为更优秀的程序员👩💻👨💻!