定义
建造者模式(Builder Pattern)是一种创建型设计模式,其主要目的是将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
意图
- 将一个复杂对象的构建过程抽象出来,使得相同的构建过程可以创建不同的表示。
- 使得客户端可以构建复杂对象的表示,而不必关心其内部的构建过程。
参与者
-
Director(指挥者): 负责使用具体建造者(Concrete Builder)的接口来构建产品对象。通常定义了一个构建方法,通过调用具体建造者的方法来构建产品。
-
Builder(抽象建造者): 定义了构建产品各个部分的抽象接口,通常包括构建产品的方法和返回产品的方法。
-
ConcreteBuilder(具体建造者): 实现抽象建造者接口,完成具体产品的构建过程。通常包括一个持有产品实例的成员变量,用于保存构建过程中的中间结果。
-
Product(产品): 表示被构建的复杂对象。通常包含多个部分,其构建过程由具体建造者来完成。
举例
以构建Person为例
类图

构建person
public class Person {
// 必要参数
private final int id;
private final String name;
// 可选参数
private final int age;
private final String sex;
private final String phone;
private final String address;
private final String desc;
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", phone='" + phone + '\'' +
", address='" + address + '\'' +
", desc='" + desc + '\'' +
'}';
}
private Person(Builder builder) {
this.id = builder.id;
this.name = builder.name;
this.age = builder.age;
this.sex = builder.sex;
this.phone = builder.phone;
this.address = builder.address;
this.desc = builder.desc;
}
public static class Builder {
// 必要参数
private final int id;
private final String name;
// 可选参数
private int age;
private String sex;
private String phone;
private String address;
private String desc;
public Builder(int id, String name) {
this.id = id;
this.name = name;
}
public Builder age(int val) {
this.age = val;
return this;
}
public Builder sex(String val) {
this.sex = val;
return this;
}
public Builder phone(String val) {
this.phone = val;
return this;
}
public Builder address(String val) {
this.address = val;
return this;
}
public Builder desc(String val) {
this.desc = val;
return this;
}
public Person build() {
return new Person(this);
}
}
}
测试
public static void main(String[] args) {
Person person = new Person.Builder(1, "张三").age(18).sex("男").desc("测试使用builder模式").build();
log.info("person info:{}",person);
}

优点:
- 分离构建过程和表示: 建造者模式将一个复杂对象的构建过程和它的表示分离开,使得同样的构建过程可以创建不同的表示,提高了灵活性。
- 更好的封装性: 客户端无需关心产品的内部构建过程,只需要关心建造者的接口,使得产品的内部结构对客户端透明,达到了更好的封装性。
- 便于扩展: 可以更容易地扩展具体建造者或改变具体产品的内部表示,而对客户端代码的影响较小。
- 更好的复用性: 可以使用相同的构建过程来构建不同的产品对象,提高了构建过程的复用性。
- 更好的控制产品的构建过程: 指挥者可以根据需要调用不同的具体建造者来构建产品,控制产品的构建过程。
缺点:
- 增加了系统的复杂性: 引入了多个新的角色和接口,增加了系统的复杂性,特别是在产品对象的部分或属性较多的情况下。
- 不适用于简单对象的构建: 如果产品对象的构建过程很简单,那么使用建造者模式可能会显得繁琐,不适合使用。
- 增加了代码量: 引入了具体建造者和指挥者,可能会增加系统的代码量。
- 客户端需要知道具体建造者: 客户端在使用建造者模式时,需要知道具体建造者的类名,这违反了依赖倒置原则,增加了客户端与具体建造者的耦合度。
建造者模式应用
StringBuilder
SpringSecurity

public SecurityFilterChain securityFilterChain(HttpSecurity http,
ClientRegistrationRepository clientRegistrationRepository) throws Exception {
http
.authorizeHttpRequests(authorize ->
authorize
.requestMatchers("/logged-out","/oauth2/token/**").permitAll()
.anyRequest().authenticated()
)
.oauth2Login(oauth2Login ->
oauth2Login.loginPage("/oauth2/authorization/messaging-client-oidc"))
.oauth2Client(withDefaults())
.logout(logout ->
logout.logoutSuccessHandler(oidcLogoutSuccessHandler(clientRegistrationRepository)));
return http.build();
}
WebClient
public WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =
new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
// @formatter:off
return WebClient.builder()
.apply(oauth2Client.oauth2Configuration())
.build();
// @formatter:on
}
分享到: