接口(接口/抽象类)不是抽象?

时间:2010-12-09 04:59:29

标签: design-patterns interface abstraction

最近,我一直在阅读那些谈论接口是抽象的错误概念的帖子。一个这样的帖子是http://blog.ploeh.dk/2010/12/02/InterfacesAreNotAbstractions.aspx

我有点困惑。如果我没有接口(接口/抽象类),那么我将如何注入我的依赖项并模拟它们?

另外,我听过人们谈论不使用只有一个实现者的接口。像这里的博客一样 - http://simpleprogrammer.com/2010/11/02/back-to-basics-what-is-an-interface/

现在所有这些,是不是违反了原则 - 编程接口而不是实现?

4 个答案:

答案 0 :(得分:6)

对接口而不是实现进行编程更多的是使用数据抽象和封装。

当我们在编程方面对接口说“接口”时。这种接口意味着类的外部方法和属性。它不必是语言级接口。 (关键字界面。)

您应该努力确保您的代码不依赖于其他类的内部细节。

答案 1 :(得分:5)

我会说我不同意链接文章中的许多要点:

  • 接口合同。合同有两部分 - 方法签名(纯语法)和文档

  • 接口抽象。我看不到LSP违规的例子。 IRectangle示例根本不是一个好例子。关于Set extends Collection,可以说同样的事情,其中​​不允许添加重复项。如果您通过Collection,您可能会感到惊讶,因此不允许重复。使用Collection接口,通过记录实现者可能添加限制来处理此问题

  • 漏洞抽象是不可避免的。但这完全取决于设计师。而btw“接口是漏洞抽象”意味着他们抽象。

  • 这些家伙似乎错过了“接触”单元测试。模拟实现是使用接口的一个很好的理由(尽管你也可以模拟具体的类)。

  • 我们当前项目的一个很好的例子 - 最初我们只有一个DAO实现 - 一个从数据库中获取东西。但后来我们将部分操作转换为专用搜索引擎。我们添加了DAO的另一个实现,然后我们去了。因此,最初的一个实现的接口得到了回报。

  • 顺便说一句,最初SortedSet在JDK中只有一个实现 - TreeSet。现在它有两个。还有更多来自外部图书馆。

  • 最后,接口(作为一种语言结构)是一种描述类功能的方法,具有禁止任何实现滑入的额外功能。即 - 接口是一种难以滥用的提供抽象的方式。

所有人都说,你不需要任何接口。但这取决于具体情况。例如,我不使用辅助类的接口。这篇文章的有效之处在于“对界面的编程”并不一定包含interface关键字。一个类的“公共接口”(理论上)是其公共方法的集合。

答案 2 :(得分:3)

只要你不过分,我相信你最好不要创建一个界面。

这是我经常遇到的一个用例,其中只有一个实现者(在我看来)非常好:你有一个Swing组件,假设它是一个CarComparisonResultsPanel,它允许用户查看结果汽车之间的比较。作为面板的用户,我宁愿使用CarComparisonResult接口只有getCarSimilarities()getCarDifferences(),而不是实现这些方法的JPanel实现以及其他几十个。

编辑:为了使我的“不要过度做”更清楚一点,这些是过度使用它的一些例子:工厂,构建器,助手/实用程序类的接口,不添加相关公共方法的GUI组件给他们的父母,......

答案 3 :(得分:0)

编程到接口背后的原则不必仅限于接口情况。当你设计你的界面时,你所问的一般问题是“我希望在哪里消费这个?由谁?为了什么目的?”即使在创建实现类时也应该询问的问题。

可能在设计界面时,您会意识到您并不需​​要将其设置为接口,并且允许重载和继承就足以进行测试。正如第一篇文章所提到的那样,如果你总是以对象和接口之间的1:1关联结束,除了“我正在编程接口”之外没有任何目的,你只是弄乱了你的代码。

但是,这并不意味着您无法继续设计类,就好像您正在为它创建一个接口/基类,使用一组提供基本功能的通用方法/属性/字段然后添加其他更具体的实现方法/属性/字段。这样做仍然是IMO,属于编程接口的原则。当一个明确的需求出现时,它肯定会为您提供一个接口/基类的门。