我们是否需要更喜欢构造函数而不是静态工厂方法?如果是,什么时候?

我一直在阅读Joshua Bloch《Effective Java》,到目前为止,它确实不辜负它的声誉。第一项为构造函数上的静态工厂方法提供了令人信服的案例。如此之多,以至于我开始质疑:)的好的旧构造函数的有效性。

本书的优点/缺点总结如下:

优势:

  1. 他们有名字!
  2. 我们有完全的实例控制(单例、性能等)
  3. 它们可以返回子类型/接口
  4. 编译器可以提供类型推断

弊:

  1. 私有类不能被子类化
  2. 它们在文档中并不像构造函数那样突出

第一个缺点实际上可能是一件好事(如书中提到的)。第二个,我认为只是一个小缺点,可以通过即将发布的java版本(javadoc的注释等)轻松解决。

看起来,最终工厂方法几乎具备了构造函数的所有优点,优点还有很多,而且没有真正的缺点!

所以,我的问题基本上分为三个部分:

  1. 默认情况下,始终使用静态工厂方法而不是构造函数是一种好的做法吗?
  2. 使用构造函数是否合理?
  3. 为什么面向对象的语言不为工厂提供语言级支持?

注意:有两个类似的问题:何时使用构造函数,何时使用getInstance()方法(静态工厂方法)?对象的创建:构造函数或静态工厂方法。然而,答案要么只是提供上面的列表,要么重申我已经知道的静态工厂方法背后的基本原理。


答案 1

静态工厂最终仍然需要调用构造函数。可以将大部分功能移动到静态工厂中,但不能避免使用构造函数。

另一方面,对于简单情况,您可以只有一个构造函数,而没有静态工厂。

构造函数是设置最终字段的唯一方法,恕我直言,这比非最终字段更可取。

您可以在子类中使用构造函数 can。不能对子类使用静态工厂。

如果你有一个很好的依赖关系注入框架来构建组件的依赖关系,你可能会发现静态工厂并没有增加太多。


答案 2

我喜欢你强调的一个类似问题的评论:

(关于如何决定是否应该偏爱工厂方法而不是构造函数),

“你需要决定你想要完成什么。要么你不希望人们调用你的构造函数(你正在创建一个单例或一个工厂),要么你不介意(就像上面的NumberFormat一样,为了方便调用者,他们正在初始化一些对象)”

对我来说,这意味着使用构造函数是合理的,其中不需要工厂方法。不需要工厂,它只会使代码更难遵循(“这里返回的确切子类?


推荐