解决了什么问题
如果一个类中有很多属性,为了避免构造函数的参数列表过长,影响代码的可读性和易用性,我们可以通过构造函数配合 set() 方法来解决。但是,如果存在下面情况中的任意一种,我们就要考虑使用建造者模式了。
- 我们把类的必填属性放到构造函数中,强制创建对象的时候就设置。如果必填的属性有很多,把这些必填属性都放到构造函数中设置,那构造函数就又会出现参数列表很长的问题。如果我们把必填属性通过 set() 方法设置,那校验这些必填属性是否已经填写的逻辑就无处安放了。
- 如果类的属性之间有一定的依赖关系或者约束条件,我们继续使用构造函数配合 set() 方法的设计思路,那这些依赖关系或约束条件的校验逻辑就无处安放了。
- 如果我们希望创建不可变对象,也就是说,对象在创建好之后,就不能再修改内部的属性值,要实现这个功能,我们就不能在类中暴露 set() 方法。构造函数配合 set() 方法来设置属性值的方式就不适用了。
如何解决的
注意点
- ResourceConfig 的构造函数需要是 private
- Builder 类成员需要与 ResourceConfig 中的保持一致
public class ResourceConfig { // 资源配置名称 private String name; // 最大资源数量,默认值 10 private int max = 10 ; // 最小资源数量,默认值 10 private int min = 10 ; private ResourceConfig(Builder builder) { this .name = builder.name; this .max = builder.max; this .min = builder.min; } // 定义类属性 get 方法 public String getName() { return name; } public int getMax() { return max; } public int getMin() { return min; } // 定义内部类 Builder public static class Builder { // 资源配置名称,必须配置 private String name; // 最大资源数量,默认值 10 private int max = 10 ; // 最小资源数量,默认值 10 private int min = 10 ; public ResourceConfig build() { // 构建前做需要的校验 if (StringUtils.isBlank(name)) { throw new IllegalArgumentException( "name not null" ); } if (max < 1 ) { throw new IllegalArgumentException( "max must be greater than or equal to 1" ); } if (min < 1 ) { throw new IllegalArgumentException( "min must be greater than or equal to 1" ); } // 类属性之间存在依赖关系 if (max < min) { throw new IllegalArgumentException( "max must be greater than or equal to min" ); } // 构建 return new ResourceConfig( this ); } // 设置相关属性 public Builder setName(String name) { this .name = name; return this ; } public Builder setMax( int max) { this .max = max; return this ; } public Builder setMin( int min) { this .min = min; return this ; } } } 如何使用 ResourceConfig resourceConfig = new ResourceConfig.Builder().setName( "lp" ).setMin( 2 ).setMax( 5 ).build(); |
参考资料
极客Time–设计模式之美-第46讲