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

This commit is contained in:
zhili 2019-07-16 16:59:58 +08:00 committed by GitHub
parent 46a3ce0480
commit 61ea173f86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -13,14 +13,14 @@ public static Boolean valueOf(boolean b) {
  类可以为其客户端提供静态工厂方法,而不是公共构造方法。提供静态工厂方法而不是公共构造方法有优点也有缺点。
  **静态工厂方法的一个优点是,不像构造方法,它们是有名字的。** 如果构造方法的参数本身并不描述被返回的对象,则具有精心选择名称的静态工厂更易于使用,并且生成的客户端代码更易于阅读。 例如,返回一个可能为素数的 `BigInteger` 的构造方法 `BigInteger(intintRandom)` 可以更好地表示为名为 `BigInteger.probablePrime` 的静态工厂方法。 (这个方法是在 Java 1.4 中添加的。)
  **静态工厂方法的一个优点是,与构造方法不同,它们是有名字的。** 如果构造方法的参数本身并不描述被返回的对象,则具有精心选择名称的静态工厂更易于使用,并且生成的客户端代码更易于阅读。 例如,返回一个可能为素数的 `BigInteger` 的构造方法 `BigInteger(intintRandom)` 可以更好地表示为名为 `BigInteger.probablePrime` 的静态工厂方法。 (这个方法是在 Java 1.4 中添加的。)
  一个类只能有一个给定签名的构造方法。 程序员知道通过提供两个构造方法来解决这个限制,这两个构造方法的参数列表只有它们的参数类型的顺序不同。 这是一个非常糟糕的主意。 这样的 API 用户将永远不会记得哪个构造方法是哪个,最终会错误地调用。 阅读使用这些构造方法的代码的人只有在参考类文档的情况下才知道代码的作用。
  因为他们有名字,所以静态工厂方法不会受到上面讨论中的限制。在类中似乎需要具有相同签名的多个构造方法的情况下,用静态工厂方法替换构造方法,并仔细选择名称来突出它们的差异。
  **静态工厂方法的第二个优点是,与构造方法不同,它们不需要每次调用时都创建一个新对象。** 这允许不可变的类 (详见第 17 条)使用预先构建的实例,或者在构造时缓存实例,并反复分配它们以避免创建不必要的重复对象。`Boolean.valueof(boolean)` 方法说明了这种方法:它从不创建对象。这种技术类似于 `Flyweight` 模式[Gamma95]。如果经常请求等价对象,那么它可以极大地提高性能,特别是如果在创建它们非常昂贵的情况下。
  **静态工厂方法的第二个优点是,与构造方法不同,它们不需要每次调用时都创建一个新对象。** 这允许不可变的类 (详见第 17 条)使用预先构建的实例,或者在构造时缓存实例,并反复分配它们以避免创建不必要的重复对象。`Boolean.valueof(boolean)` 方法说明了这种方法:它从不创建对象。这种技术类似于 `Flyweight` 模式[Gamma95]。如果经常请求等价对象,那么它可以极大地提高性能,特别是在创建它们的代价非常昂贵的情况下。
  静态工厂方法从重复调用返回相同对象的能力允许类保持在任何时候存在的实例的严格控制。这样做的类被称为实例控制instance-controlled。编写实例控制类的原因有很多。实例控制允许一个类来保证它是一个单例详见第 3 条)项或不可实例化的(详见第 4 条)。同时,它允许一个不可变的值类(详见第 17 条)保证不存在两个相同的实例:当且仅当 `a == b``a.equals(b)`。这是享元模式的基础[Gamma95]。`Enum` 类型(详见第 34 条)提供了这个保证。