读书笔记 仅供参考
静态工厂和构造器的局限性
不能很好地扩展到大量的可选参数
重叠构造器模式
提供一个只有必要参数的构造器,其余构造器逐渐增加可选参数,直到最后一个构造器包含所有可选参数
public class NutritionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
//两个必要参数
public NutritionFacts(int servingSize, int servings) {
this(servingSize, servings, 0);
}
//一个可选参数
public NutritionFacts(int servingSize, int servings
, int calories) {
this(servingSize, servings, calories, 0);
}
//两个可选参数
public NutritionFacts(int servingSize, int servings
, int calories, int fat) {
this(servingSize, servings, calories, fat ,0);
}
//所有可选参数
public NutritionFacts(int servingSize, int servings
, int calories, int fat, int sodium) {
this.servingSize = servingSize;
...
this.sodium = sodium;
}
}
随着参数的增加,程序很快会失去控制,客户端代码会很难编写,并且难以阅读。
JavaBeans 模式
即利用 setter 和 getter 方法来设置参数,我从最开始写 java 代码就使用这种方式。这种方式与前后两种还有一个区别:属性不能设为 final,即不可作为不可变类。
public class NutritionFacts {
private int servingSize;
private int servings;
private int calories;
private int fat;
private int sodium;
public void setServingSize(int servingSize) {
this.servingSize = servingSize;
}
...
}
因为构造过程被分到多个调用中,在构造过程中 JavaBeans 可能处于不一致的状态,试图使用不一致状态的对象,将会导致失败。另外一点不足:JavaBeans 模式组织了将类作为不可变类的可能,需要付出额外努力确保线程安全
ps:不一致的状态:不是很理解这个概念,在网上查询的结果是:同一个构造器产生的对象,但是最后对象的属性却大相径庭。或者理解为,在还没有为对象 set 必要属性的时候,就使用对象,会导致错误(这个倒是我时常会发生的错误)。
Builder 模式
先产生一个 builder 对象,再在 builder 对象上调用类似 setter 的方法,设置可选参数,最后利用无参的 build 方法生成不可变的对象。
public class NutritionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
//必选参数
private final int servingSize;
private final int servings;
//可选参数,要有默认值
private int calories = 0;
private int fat = 0;
private int sodium = 0;
public Builder(int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
}
public Builder calories(int val) {
caolries = val;
return this;
}
public Builder fat(int val) {
fat = val;
return this;
}
public Builder sodium(int val) {
sodium = val;
return this;
}
public NutritionFacts build() {
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder) {
servingSize = builder.servingSize;
...
}
}
//调用方式
NutritionFacts fact = new NutritionFacts.Builder(240, 8).
calories(100).sodium(35).build();
builder 可以对参数进行检验,如果违反了约束就抛出异常。也可以在 setter 方法(builder 模式的 setter)中对参数进行检验,不在 builde() 方法中检验。
设置了参数的 builder 生成了一个抽象工厂,用泛型满足所有的 builder
public interface Builder<T> {
public T build();
}
Builder 模式的不足在于创建 builder 的性能损耗,在十分注重性能的情况下,会成为问题, Builder 模式比重叠构造器还冗长,所有只有在有很多参数的情况下才使用。
本文对比了静态工厂、重叠构造器、JavaBeans及Builder四种构造模式的优缺点,着重介绍了每种模式的应用场景及其可能导致的问题。

2157

被折叠的 条评论
为什么被折叠?



