01.考虑使用静态工厂方法替代构造方法

在一个类中,可以考虑使用静态工厂方法来返回这个类的对象。

public static Boolean valueOf(boolean b) {
    return (b ? TRUE : FALSE);
}
  • 静态工厂方法的一个优点是,不像构造方法,它们是有名字的。

静态工厂方法具有名称,使得生成的客户端代码更易于阅读,而构造方法如果参数本身并不描述被返回的对象。如上面的代码中,可以使用一个构造方法实现,但是这种实现方式下,调用者仅知道返回一个Boolean类型的对象,但是并不知道对象中具体的指。而使用valueOf方法,则可以描述该方法的执行结果,调用方可以知道返回的Boolean对象的指即为传入的boolea值。

  • 静态工厂方法的第二个优点是,与构造方法不同,它们不需要每次调用时都创建一个新对象。。
/**
 * The {@code Boolean} object corresponding to the primitive
 * value {@code true}.
 */
public static final Boolean TRUE = new Boolean(true);
/**
 * The {@code Boolean} object corresponding to the primitive
 * value {@code false}.
 */
public static final Boolean FALSE = new Boolean(false);

如上案例,在Boolean类中,默认创建了两个静态常量,当使用valueOf方法时,不再需要每次创建新的对象,而是直接返回前面已经定义好的对象即可。

  • 静态工厂方法的第三个优点是,与构造方法不同,它们可以返回其返回类型的任何子类型的对象。

在通过构造方法创建对象时,只能返回当前类的对象。但是我们可以通过提供一个静态工厂返回其子类或者当前类的私有内部类的对象,如CollectionsemptyList()方法。

public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
}

同理,我们可以提供一个静态方法,接收一个参数,在方法体中根据传入的参数创建不同的类对象。

  • 静态工厂的第 5 个优点是,在编写包含该方法的类时,返回的对象的类不需要存在。

这里可以参考 java.sql.DriverManager 中的实现。其中,java.sql.Driver 接口作为服务接口提供接口定义。java.sql.DriverManager#registerDriver(java.sql.Driver, java.sql.DriverAction) 作为 提供者注册 API,提供者用来注册实现;java.sql.DriverManager#getDriver 作为访问api提供给调用方获取具体的实例。在编写DriverManager类时,Dricer类的实现不需要存在,后续的实现类只需要添加到环境中,并调用register方法注册,完成后即可被客户端调用。

只提供静态工厂方法的主要限制是,没有公共或受保护构造方法的类不能被子类化。然而,这也可以看作是一种优点,因为它鼓励程序员使用组合而不是继承,并且有利于实现不可变类型。

类似文章