我认为标题本身就说明了 - 为什么我应该编写一个接口然后实现一个具体的类,如果只有这个接口的1个具体实现呢?
答案 0 :(得分:36)
我认为你不应该;)
没有必要用相应的接口遮蔽所有类。
即使您稍后要进行更多实施,也可以在必要时随时提取界面。
答案 1 :(得分:13)
这是粒度的问题。您不能使用不必要的接口使代码混乱,但它们在层之间的边界处很有用。
有一天,您可能会尝试测试依赖于此接口的类。那么你可以嘲笑它很好。
我经常创建和删除接口。有些人不值得努力,有些人真的需要。我的直觉大多是正确的,但一些重构是必要的。
答案 2 :(得分:5)
问题是,如果只有一个具体的实现,是否应该有一个接口?
答案 3 :(得分:2)
YAGNI - 你不需要Wikipedia
根据那些主张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.
答案 4 :(得分:1)
您的问题有两个有些矛盾的答案:
大多数系统(甚至是“一次性代码”)的发展和变化都远远超过了原始设计的目标。接口通过减少耦合帮助它们灵活地增长。通常,以下是您应该编写接口的警告信号:
如果你可以诚实地对所有这些问题回答“否”,那么界面可能过度。威力。但同样,不可预见的后果是编程中游戏的名称。
答案 5 :(得分:1)
您需要通过指定公共函数来确定编程接口是什么。如果你没有做好这个,那么这个课就很难用了。
因此,如果您稍后决定需要创建正式的界面,那么您应该准备好设计。
因此,您需要设计一个接口,但不需要将其作为接口编写,然后实现它。
答案 6 :(得分:1)
我使用测试驱动的方法来创建我的代码。这通常会让我创建接口,我想在我的测试夹具中提供模拟或虚拟实现。
我通常不会创建任何代码,除非它与我的测试有关,并且因为你不能轻易地测试一个接口,只有一个实现,这导致我在为测试用例提供依赖项时需要它们时创建接口。
我有时也会在重构时创建接口,以消除重复或提高代码可读性。
如果您以后发现需要,可以随时重构代码以引入界面。
唯一的例外是,如果我正在设计一个API以便发布给第三方 - 其中API更改的成本很高。在这种情况下,我可能会尝试预测将来可能需要做的更改类型,并找出创建API的方法,以最大限度地减少将来不兼容的更改。
答案 7 :(得分:1)
还有一件事没有人提到过,有时候为了避免依赖性问题是必要的。您可以在具有少量依赖项的公共项目中使用该接口,并在具有大量依赖项的单独项目中实现该接口。
答案 8 :(得分:0)
“只有一次实现”==着名的最后一句话
创建一个接口然后从中派生一个具体的类并不需要花费太多。这样做的过程可以让您重新考虑您的设计,并经常导致更好的最终产品。一旦你完成它,如果你发现自己正在吃这些话 - 经常发生 - 你就不必担心它。你已经准备好了。否则你有一堆重构要做,这将是一种痛苦。
编辑澄清:我正在假设这个课程将会相对广泛地传播。如果它是由一个或两个其他类在一个包中使用的小实用程序类,那么是的,不要担心它。如果它是一个将由多个其他类在多个包中使用的类,那么我之前的答案适用。
答案 9 :(得分:0)
问题应该是:“你怎么能确定,只有一个具体的实施?”
你怎么能完全确定?
当你想到这一点时,你已经创建了界面并且在没有假设的情况下继续前进,可能会出错。
使用今天的编码工具(如Resharper),实际上并不需要花费太多时间来创建和维护类与您的类一起,而发现现在需要额外的实现并替换所有具体的引用可能需要很长时间时间并没有任何乐趣 - 相信我。
答案 10 :(得分:0)
其中很多内容来自于InfoQ上的Rainsberger演讲:http://www.infoq.com/presentations/integration-tests-scam
有一个课程有三个理由:
大多数服务都应该有接口。它创建了一个边界,隐藏了实现,你已经有了第二个客户端;所有与该服务交互的测试。
基本上,如果你想在单元测试中模拟它,它应该有一个接口。