【发布时间】:2014-10-14 21:25:07
【问题描述】:
最近,我正在就这个问题进行激烈的讨论。
假设我在 Java 中创建了这个方法:
public Set<String> getRich() {
return ImmutableSet<String> ....;
}
每当我在拉取请求中看到这一点时,我都会大喊大叫并试图解释为什么它是错误的。通过这样做,我误导了我的方法的消费者,因为他们会得到一个 Set 的承诺。这意味着他们可以删除或添加元素。 javac 会很高兴地编译它,但会抛出 RuntimeException。此外,它违反了“Liskov 替换原则”。
就个人而言,我总是这样做:
public ImmutableSet<String> getRich() {
return ImmutableSet<String> ....;
}
这样,没有人会朝自己的脚开枪。
一种建议的方法是返回 Iterable。我认为这很糟糕,因为该方法的使用者将失去 HashSet、HashMap 或其他任何东西的潜在功能(无法调用 set.get(hash) )。
另一种方法是 - 作为消费者 - 创建 getRich() 方法的输出的副本。但是你如何确定消费者会这样做呢?
当然,有些人会坚持 OOP 设计原则并说:“始终针对接口编程”。对我来说——在这种特殊情况下——这是有史以来最糟糕的选择。
你会如何处理这个案子?
(题外话:这个案例是一个完美的例子,静态类型如何确保正确性,但永远无法确保正确性)。
【问题讨论】:
-
问题从 ImmutableSet 实现 Set 的地方开始,即使实现没有...
标签: java oop inheritance design-patterns immutability