我们为什么要将接口与使用它们的类放在一起而不是那些实现它们的类?

时间:2011-04-30 07:11:08

标签: oop design-patterns packages

我正在阅读罗伯特·C·马丁的一篇文章,并在一个地方举了这样一个例子:

第一张图片显示两个包之间存在循环依赖关系。要删除此依赖项,将在第二个映像中添加新接口。 B实现接口,Y使用它。马丁提出以下观点:

  

接口通常包含在使用它们的包中,而不是包含在中   实现它们的包。

我的问题是,我们为什么要这样安排接口?这种方式包装接口背后的原因是什么?根据Common Closure Principle,一起改变的类应该保持在一起。在变化方面,接口是否更接近其实施者或其用户

enter image description here

5 个答案:

答案 0 :(得分:9)

从技术上讲,用户并不比实现者更接近界面。在变化方面,当界面发生变化时,都需要改变。

但是,界面为什么会改变?

用户调用接口,因此它可以独立于任何可用的实现者。因此,界面的定义取决于用户的需求。

当用户指定接口的定义时,如果用户不需要接口,则无需更改接口。需要更改接口以适应实现的实现者应该发送红色标记。为什么它需要来自用户的更多或不同的信息?对用户有什么用处?

此外,实现者“仅仅”依赖于接口,因为它需要为接口中的每个方法提供实现。但它可以自由地提供空的存根,实质上是向客户提供NOP。

因此,用户需要驱动对接口的更改,并且对接口驱动器的更改将更改为实现者。因此,用户在功能上比实现者更接近界面。这是一个很好的例子来声明与用户的接口,而不是实现者。

答案 1 :(得分:2)

首先应该说没有一种方法可以给猫皮肤。

当在多个项目团队之间拆分项目或创建具有解耦子系统的系统时,此特定方法非常有用。该接口充当两个子系统之间的“契约”。通过将界面放置在“他们的地盘”上,消费方可以更好地保证界面保持不变,除非执行方联系消费方以请求这样的改变。

答案 2 :(得分:1)

通常我们使用接口作为服务器和客户端之间的协议,以便客户端知道哪些服务可用但是这种方法有副作用,客户端将依赖于服务器,因此如果服务器端发生了某些变化这会影响客户端应该更改的给定接口。 因此,罗伯特·C·马丁发明的SOLID原则中有这个原则,那就是“Dependency Inversion Principle”或“DIP”,正如其名称所暗示的那样,我们应该颠倒它之间的依赖关系。客户端和服务器,以避免客户端在未来发生变化。在这种方法中,客户端通过接口说出它需要什么,服务器应该实现它以满足它的需要,因此服务器端没有任何变化使我们改变客户端。

答案 3 :(得分:0)

没有理由在需要它之前实现接口。 YAGNI。

答案 4 :(得分:0)

这是组件ABXY之间解决循环依赖关系的问题。没有另一个就无法编译。 AB引用XYXY引用AB

罗伯特C.马丁正在应用 InversinOfControl 模式来解决这个问题

现在XY引用了ABInterfaceABInterface根本不需要知道XY

你是对的,这违反了凝聚力(你称之为普通关闭原则)

它也与KeepItSimple原则相矛盾。最简单的解决方案只有一个单一组件ABXY更难维护。