3

为什么用静态工厂替代构造函数?

 1 year ago
source link: https://www.jdon.com/61822
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

为什么用静态工厂替代构造函数?
为什么我们不能再有正常的、简单的构造函数呢?
每个JDK的新功能都会使用那些恼人的 "of(value)"、"newAbcd()"、"of()"。
在某些情况下,我同意需要使用它,例如接口(Path.of()),但我觉得它真的被过度使用了。
如果只是 "of()",没有参数,那就更奇怪了,"of "这个词不应该被使用(HexFormat.of())。
而当使用newAbcd()的样式时,会变得非常长:HttpClient httpClient = HttpClient.newHttpClient(); ...
现在,没有参数的 "of() "与 "newAbcd() "也有不一致的地方。

JDK9废止了一个超级通用的构造函数而改用静态工厂方法,我真的不喜欢这样。
在JDK 19中,他们已经废弃了new Locale(),增加了Locale.of()。
我明白这是为了缓存,但我真的觉得这不是一个好方法,它只是在不同的类中增加了很多不一致的情况。

我更喜欢大多数东西只是new Abcd()的时候。

静态工厂本身具有描述性
Instant就是这种模式的一个正确例子。Instant.now()清楚地表明了你得到的东西,ofEpochSecond/ofEpochMili也是如此(另外,由于两者都接受一个long,它们无论如何不能作为重载构造函数存在)。

至于HexFormat。是的,of()不是一个好名字。但它不能把构造函数公开,因为它是一个基于值的类。
一旦项目Valhalla到来,这些就会变成值类,不幸的是,这样做是对构造函数的字节码不兼容的改变。因此,他们确保JDK中所有基于值的类都有私有构造函数。

构造函数缺点
构造函数不够灵活。你可能想用另一个类来实现。你可能想提供更具描述性的名字。你可能想做一些缓存。也许现在不需要,但在不破坏合同的前提下,保持这种可能性。

现在我并不鼓励大家在自己的代码中用工厂来取代构造函数。但对于库来说,这可能是有意义的。

静态工厂好处
这个话题在Effective Java中得到了很好的覆盖。

关于静态工厂方法的总结:

优点

  • 它们可以有描述性的名字
  • 它们不需要创建一个新的对象(如Locale缓存的例子)。
  • 它们可以返回其返回类型的任何子类型
  • 返回的类可以根据输入参数而变化
  • 在编写方法时,返回对象的类不需要存在(如服务提供者框架)。

限制

  • 没有构造函数的类不能被子类化

of取名问题
of()看起来很奇特,但这是一个典型的实用主义权衡的例子。
由于new关键字的存在,他们不能使用new(),所以他们必须选择别的方法。
对于非零参数的工厂方法,of(...)往往是new()的一个相当安全和合理的替代品,因为实现不需要一个专门的名字。
由于of(...)已经被接受为new(...)的替代品(而且已经被接受了很多年),所以没有太多理由花费额外的精力去寻找new()这个特殊情况的可接受的替代品,所以of()被类似地重复使用。
此外,由于没有选择其他的东西,所有的of*(*)名称都会在标识符列表中被分组,也许最重要的是在完成建议中。即使他们可以修改语言以允许new()方法,这也不是一个好主意,因为new操作符有常规方法所不提供的特殊保证。

of()孤立地看不是一个好名字,但在实践中却是一个很好的名字。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK