13

我一直在阅读Joshua Bloch的《 Effective Java》,到目前为止,它确实名副其实。第一项为静态工厂方法优于构造函数提供了一个令人信服的案例。以至于我开始质疑好的旧构造函数的有效性:)。

本书的优缺点总结如下:

好处:

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

缺点:

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

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

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

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

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

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

4

4 回答 4

7

静态工厂最后还是要调用构造函数。您可以将大部分功能移入静态工厂,但不能避免使用构造函数。

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

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

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

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

于 2012-03-09T15:09:15.377 回答
3

我喜欢您强调的类似问题之一的评论:

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

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

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

于 2012-03-09T15:11:02.123 回答
3

我在这里与 Josh Bloch 非常一致,他比我做得更好,但这里有几个地方不适合静态工厂:

  • 当依赖注入更明智时;DI 系统(当然是 Guice)倾向于通过它们的构造函数注入东西。特别是,当您预计构造函数的参数将来可能会更改时,DI 是合适的。
  • 当您特别打算让人们编写子类时,您正在为他们提供一个框架来实现。
于 2012-03-09T19:53:47.410 回答
0

构造函数很无聊,你确切地知道在哪里搜索它们,你知道它们的范围,它们在某种程度上是可预测的。他们在那里建造物体本身,而不是做神一样的工作。如果你做了太多其他与构造对象没有太大关系的事情,你就知道你做错了什么。仅仅通过重命名方法是不可能“治愈”的。因此,当您没有顶级开发人员时,他们往往更专注,代码质量“更好”。(当你有后者​​时,我提到的观点并不重要。)

无聊的东西。让我们做一些更有趣和更具智力挑战性的事情......

仅作记录:我没有忽略问题和其他答案中提到的要点,我只是想添加这一点。

于 2012-03-09T20:18:26.303 回答