今天是:
带着程序的旅程,每一行代码都是你前进的一步,每个错误都是你成长的机会,最终,你将抵达你的目的地。
title

建造者模式(Builder Pattern)

定义

建造者模式(Builder Pattern)是一种创建型设计模式,其主要目的是将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。

意图

  • 将一个复杂对象的构建过程抽象出来,使得相同的构建过程可以创建不同的表示。
  • 使得客户端可以构建复杂对象的表示,而不必关心其内部的构建过程。

参与者

  1. Director(指挥者): 负责使用具体建造者(Concrete Builder)的接口来构建产品对象。通常定义了一个构建方法,通过调用具体建造者的方法来构建产品。

  2. Builder(抽象建造者): 定义了构建产品各个部分的抽象接口,通常包括构建产品的方法和返回产品的方法。

  3. ConcreteBuilder(具体建造者): 实现抽象建造者接口,完成具体产品的构建过程。通常包括一个持有产品实例的成员变量,用于保存构建过程中的中间结果。

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

建造者模式应用

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
    }

 

分享到:

专栏

类型标签

网站访问总量