与内部实现的接口 - 好的或坏的

时间:2012-06-04 16:01:46

标签: java interface coding-style

我正在开发一个包含许多someInterface的项目 - someInterfaceImpl-pairs。几天前,我得到了这个想法(可能是通过阅读一些客观的c代码来启发),将默认实现包含在内部类中。 现在有些同事(都有比我更多的java经验)看到了这个想法 - 反馈是震惊和惊讶之间(“这有效吗?”)。

我google了一下,但没有发现这个“模式”的有用性的证据(个人我喜欢它): pdf-papera faq about code style

您如何看待 - 特别是在“默认”实施与接口紧密耦合的情况下。

更新 我刚刚发现了这个:Java Interface-Implementation Pair

(见接受的答案)

3 个答案:

答案 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文件中有太多代码,但你也不想要太少。