Open igaozp opened 6 years ago
设想一下一个类有许多的属性,这些属性需要使用构造方法初始化,大量的构造方法可能会造成代码的可读性下降。如果使用 JavaBeans
模式,通过 set
方法初始化相应的属性,可能会导致对象实例处于不一致的状态,无法保证线程安全。
这样就产生了一种替代方法,通过 Builder 模式
不直接生成对象,而是利用必要的参数调用构造器,得到一个 builder 对象,通过 builder 对象设置可选参数,最后调用无参的 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 carbohydrate;
public static class Builder {
// 必要参数
private final int servingSize;
private final int servings;
// 可选参数
private int calories = 0;
private int fat = 0;
private int carbohydrate = 0;
private int sodium = 0;
public Builder(int servingSize, int servings) {
this.servingSize = servingSize;
thus.servings = servings;
}
public Builder calories(int val) {
calories = val;
return this;
}
public Builder fat(int val) {
fat = val;
return this;
}
public Builder carbohydrate(int val) {
carbohydrate = val;
return this;
}
public Builder sodium(int val) {
sodium = val;
return this;
}
public NutritionFacts build() {
return NutritionFacts(this);
}
}
private NutritionFacts(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
}
使用示例:
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();
Singleton
是指仅实例化一次的类,有多种方式实现 Singleton 类
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
}
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
public static Elvis getInstance() {
return INSTANCE;
}
}
public enum Elvis {
INSTANCE;
}
通常有一些工具类没有实例化的必要,只是使用类的静态函数或者变量,可以将类的构造器设置为 private
来避免类的实例化
public class UtilityClass {
private UtilityClass() { ... }
}
避免创建不必要的对象,尽量重用已有的对象,避免重复创建对象产生的开支,可以使用静态工厂方法来实现对相关对象的重用。优先使用基本类型,避免因自动装箱而产生性能开支。
Java 虽然不像 C++ 那样需要程序员手动管理内存,但是垃圾回收机制并不是那么智能,对于被引用的对象,就算我们已经不在使用,但是 Java 的回收机制是不会回收它们的,无意识的引用造成了 “内存泄漏”。这就需要我们手动去消除过期的对象引用,最为常用的方法将不再使用的对象设置为 null
。
C++ 的类中存在析构函数,当类的实例销毁时就会执行析构函数,Java 中也存在类似的机制那就是终结方法finalize()
,但终结方法并不能保证会被及时的执行,因此导致终结方法失去了一定的实际意义。例如数据库连接的关闭、数据流的关闭等操作可以使用 try-finally
语句来代替。
考虑使用静态工厂方法替代构造器
一个简单的示例
这样做的优点
主要的缺点