我正在开发一个包含许多someInterface的项目 - someInterfaceImpl-pairs。几天前,我得到了这个想法(可能是通过阅读一些客观的c代码来启发),将默认实现包含在内部类中。 现在有些同事(都有比我更多的java经验)看到了这个想法 - 反馈是震惊和惊讶之间(“这有效吗?”)。
我google了一下,但没有发现这个“模式”的有用性的证据(个人我喜欢它): pdf-paper 和 a faq about code style
您如何看待 - 特别是在“默认”实施与接口紧密耦合的情况下。
更新 我刚刚发现了这个:Java Interface-Implementation Pair
(见接受的答案)
答案 0 :(得分:8)
接口的重点是将用户与实现分开(默认与否)。你通过将实现包含在内部类中来打败它。您并没有真正保存任何代码行,而且会使API混乱。您最终必须做一些事情来隐藏接口用户的内部类,比如将其设置为私有或默认范围,最好避免使用它。此外,如果您的默认实现需要更改但您已将该接口作为API的一部分发布,该怎么办?这是一个坏主意,因为它没有很多好处,而且是一种反模式。
最后,如果你真的有一个默认实现,那么也许它应该是一个基类(而不是一个接口),其他实现扩展了类和覆盖行为。
我认为这篇文章对类似的问题进行了有趣的讨论: Question
答案 1 :(得分:1)
我同意上面的答案,但在某些情况下,包括实施是合乎逻辑的,例如:
答案 2 :(得分:1)
如果您的默认实现相当简单并且可能保持,和,如果没有任何扩展或可能,那么这可能就是这样。你不想把它放在自己的文件中,你还会把它放在哪里?我建议使用公共实例将该类设为私有(假设没有状态):
/** An interface a lot like java.util.Collection. */
public interface WhatEver {
private class Default implements Whatever {
// Methods...
}
/** A default implementation that is always empty. Suitable as a NULL value. */
public final WhatEver DEFAULT = new Default();
// Rest of interface...
我认为它不会对执行产生任何影响(类实例中没有数据),但你会得到更好的Javadoc。您可以使用匿名类并保存一行代码。
您甚至可能需要其他一些“默认”实例。对于类似集合的接口,您可能拥有一个具有单个默认条目的接口,或者具有相同默认条目的无限数字(hasNext
始终返回true
)。
我认为关键是默认实现不能依赖于界面之外的任何东西。除非在接口的主体中正确引用外部类和接口,否则不使用外部类和接口,并且没有外部类扩展默认值。界面变得比界面的标准概念更多,但仍然独立。
另一个关键点是你不希望在一个.java文件中有太多代码,但你也不想要太少。