Interface 即使我只打算实现一个接口,我是否仍要为接口编写代码?

Interface 即使我只打算实现一个接口,我是否仍要为接口编写代码?,interface,implementation,Interface,Implementation,我认为标题本身就说明了问题,伙计们,如果接口只有一个具体实现,为什么我要编写一个接口,然后实现一个具体类呢?问题是,如果只有一个具体实现,那么应该有接口吗?我想你不应该;) 没有必要用相应的接口来隐藏所有类 即使以后要进行更多的实现,也可以在必要时提取接口。这是粒度的问题。您不能用不必要的接口使代码混乱,但它们在层之间的边界上很有用 有一天,您可能会尝试测试依赖于此接口的类。那你可以嘲笑它就好了 我不断地创建和删除接口。有些不值得努力,有些确实需要。我的直觉基本上是正确的,但是一些重构是必要的。

我认为标题本身就说明了问题,伙计们,如果接口只有一个具体实现,为什么我要编写一个接口,然后实现一个具体类呢?

问题是,如果只有一个具体实现,那么应该有接口吗?

我想你不应该;)

没有必要用相应的接口来隐藏所有类


即使以后要进行更多的实现,也可以在必要时提取接口。

这是粒度的问题。您不能用不必要的接口使代码混乱,但它们在层之间的边界上很有用

有一天,您可能会尝试测试依赖于此接口的类。那你可以嘲笑它就好了

我不断地创建和删除接口。有些不值得努力,有些确实需要。我的直觉基本上是正确的,但是一些重构是必要的。

只有一个实现“==著名的遗言

制作一个接口并从中派生出一个具体的类并不需要花费很多。这样做的过程可以让你重新思考你的设计,并往往导致更好的最终产品。一旦你做到了,如果你发现自己像经常发生的那样吃了这些话,你就不必担心了。你已经准备好了。否则,你会有一大堆重构工作要做,这将是一件痛苦的事情


编辑澄清:我是基于这样一个假设工作的:这个类将被相对广泛地传播。如果它是一个由一个或两个其他类在单个包中使用的小型实用程序类,那么是的,不用担心。如果一个类将被多个其他类在多个包中使用,那么我前面的答案适用。

对您的问题有两个相互矛盾的答案:

  • 您不需要从构建的每个具体类中提取接口,并且
  • 大多数Java程序员没有构建他们应该构建的那么多接口
  • 大多数系统(甚至是“一次性代码”)的发展和变化远远超出了它们最初的设计意图。接口通过减少耦合帮助它们灵活增长。通常,以下是您应该对接口进行编码的警告标志:

  • 您是否怀疑另一个具体的类可能需要相同的接口(比如,如果您怀疑数据访问对象可能需要XML表示——这是我经历过的)
  • 您是否怀疑您的代码可能需要位于Web服务层的另一端
  • 您的代码是否为某些外部客户端形成了服务层
  • 如果您能诚实地回答所有这些问题“不”,那么接口可能会有些过分。可以但是,在编程中,不可预见的后果是游戏的名称。

    问题应该是:“你怎么能确定,只有一个具体的实现?”

    你怎么能完全肯定

    当您仔细考虑这一点时,您已经创建了接口,并且没有可能被证明是错误的假设


    使用当今的编码工具(如Resharper),在类旁边创建和维护接口实际上不需要花费太多时间,然而,发现现在您需要一个额外的实现并替换所有具体的引用可能需要很长时间,一点也不有趣-相信我。

    您需要通过指定公共函数来决定编程接口是什么。如果你做得不好,这个课程就很难使用

    因此,如果您以后决定需要创建一个正式的接口,那么应该准备好设计


    因此,您确实需要设计一个接口,但不需要将其编写为接口,然后实现它。

    这其中很多内容来自InfoQ上的Rainsberger谈话:

    开设一门课程有三个原因:

  • 它有一些价值
  • 它有助于保持某种实体
  • 它提供一些服务
  • 大多数服务都应该有接口。它创建了一个边界,隐藏了实现,并且您已经有了第二个客户端;与该服务交互的所有测试


    基本上,如果你想在单元测试中模拟它,它应该有一个接口。

    YAGNI-你不需要它

    根据那些提倡YAGNI方法的人的观点,编写目前不必要但将来可能需要的代码的诱惑有以下缺点:

    * The time spent is taken from adding, testing or improving necessary functionality.
    * The new features must be debugged, documented, and supported.
    * Any new feature imposes constraints on what can be done in the future, so an unnecessary feature now may prevent implementing a necessary feature later.
    * Until the feature is actually needed, it is difficult to fully define what it should do and to test it. If the new feature is not properly defined and tested, it may not work right, even if it eventually is needed.
    * It leads to code bloat; the software becomes larger and more complicated.
    * Unless there are specifications and some kind of revision control, the feature may not be known to programmers who could make use of it.
    * Adding the new feature may suggest other new features. If these new features are implemented as well, this may result in a snowball effect towards creeping featurism.
    

    我使用测试驱动的方法来创建代码。这通常会导致我创建接口,我希望在其中提供模拟或虚拟实现作为测试夹具的一部分

    我通常不会创建任何代码,除非它与我的测试有一定的相关性,并且因为您无法轻松地测试接口,而只能测试一个实现,如果我在为测试用例提供依赖项时需要创建接口,它会引导我创建接口

    我有时还会在重构时创建接口,以消除重复或提高代码可读性

    如果以后发现需要接口,您可以随时重构代码以引入接口


    唯一的例外是,如果我设计了一个API发布给第三方——在第三方进行API更改的成本很高。在这种情况下,我可能会尝试预测未来可能需要做的更改类型,并找出创建API的方法,以尽量减少未来不兼容的更改。

    有一件事还没有人提到,那就是有时为了避免依赖性问题,这是必要的。您可以在具有少量依赖项的公共项目中使用接口,在sepa中使用实现