依赖性反转和分离的接口模式(或一般的接口代码)之间有什么区别?

时间:2013-12-20 09:17:24

标签: java interface dependency-inversion

我无法弄清楚依赖性倒置原则(S.O.L.I.D原则之一)与一般“代码到接口”或分离接口模式之间的区别。所有这些都提倡创建一个抽象层来解耦较低级别和较高级别的模块。

DI原则设想创建在更高层和更低层模块之间交互的接口,但也坚持接口必须是更高层包的一部分。
为什么这应该是更高层次而不是更低层次的一部分?它是暴露其行为的较低级别,所以解耦接口不应该是较低级别的一部分吗? 如果有多个更高级别的模块取决于相同的较低级别怎么办?

否则,
为什么不制作一个单独的包来放置所有接口,然后可以被更高级别和更低级别使用? (这是由分离的接口模式设想的。)

我的困境是,我无法弄清楚它们的相对用途和好处。

请不要引用Derek Greer或Robert Martin的文章。我读过那些文章,但是仍然存在混淆。

3 个答案:

答案 0 :(得分:4)

依赖性反转是对依赖注入框架(如Spring,Guice等)构建块的概念。它所说的是组件不应该查找其依赖性,而应该从外部注入其依赖性。组件的依赖关系可以是接口或另一个类。当依赖是一个接口时,该组件可以灵活地使用各种实现。

让我们举一个例子:假设某人正在编写一个需要进行一些服务调用的组件。如果组件开发人员认为必须始终使用HTTP进行服务调用,那么她将使HTTP客户端成为依赖关系。现在,这限制了组件实用程序只能调用基于HTTP的服务。但是,同样的开发人员可以创建一个接口,比方说--GenericExternalServiceInvoker,并实现了两个实现 - 一个使用HTTP,另一个使用某种排队系统,如ActiveMQ。使用接口使组件开发人员能够以更广泛的方式创建有用的组件。

在上面的例子中,我们假设DI已到位。因为依赖是从外部注入的。组件开发人员可能已经做出了另一个设计选择,并且可能在代码中实例化了HTTP客户端,因此如果需要,组件用户很难改变其行为,使用除HTTP之外的其他东西。

因此,总而言之,应该使用DI,以便组件不依赖于其以硬连线方式的依赖性。通过使组件的依赖性成为一个接口,进一步的灵活性可以构建到组件中。第二个原则,Code to interfaces,是开发人员选择接口作为依赖而不是具体类的指导因素。

答案 1 :(得分:1)

我想你的意思是依赖注入 编程到接口

之间的区别

编程到接口

接口编程是软件开发中的一种实践,其中不同的对象通过公共接口相互交互。这样可以提供更大的灵活性,因为可以轻松地从一个接口实现切换到另一个接口实现,只需对代码库进行最少的更改,甚至可以避免重新编译代码。

依赖注入

依赖注入是一种允许框架而不是开发人员创建对象实例的机制。在大多数情况下,对象可能需要一些其他对象(称为依赖)到已经存在并在当前对象的构造函数中传递,或传递给该对象的属性,以使其可用。依赖注入是一种机制,允许框架在构造所需对象(注入它们)时提供设置这些。通常,框架根据外部配置或代码检查知道要做什么 依赖注入范例依赖于编程到接口实践(这就是我先描述它的原因),因为依赖关系通常通过它们的公共接口公开。因此,可以仅基于配置改变来使用不同的实现。这样可以在测试应用程序的某些方面时轻松使用对象的模拟设置。

通常,依赖注入被称为反转控制机制,因为它导致框架(意味着应用程序代码)处理对象创建而不是手动实例化(由开发人员完成)。

根据{{​​3}}的评论

  

依赖注入是否与依赖反转相同?

不一定。依赖 inversion 也可以称为反映两个对象之间依赖关系的重构过程。例如,class A可能依赖于class B 之前的重构,而 之后您可能class B依赖于class A相反,因此反转他们的依赖。依赖注入提供依赖关系的机制,无需明确编写代码。

<强>更新

有关术语依赖性反转的更多信息,建议您阅读Rich Newman的aknon。它是解决Microsoft智能客户端软件工厂技术(现在已经过时)的系列文章的一部分,但该文章足够中立,可以独立存在。


另见:

答案 2 :(得分:0)

复杂依赖注入通常需要编程反转接口。我不认为将API放在单独的模块中,或者只是放在不同的包中,或者并排实现原则上正确错误 。这取决于:我见过的大多数项目都将捆绑接口和实现捆绑在一起,但有时候api二进制文件甚至会在不同的存档中提供,例如servlet-api.jarlogging-api.jar

事实上,我认为在比较这两个细节时没有任何价值。过了一段时间,我认为常识是唯一始终适用的原则,在阅读方法/模式时,无论人们应该考虑什么,作者都会出售书籍,在会议和一般会议上发言从中做生意。这并不是说这些读数毫无用处,恰恰相反:它们是从别人的成功和失败中学习的基本方式。但是,这些论点应该用一点点考虑,因为解决方案可能不适合特定的项目。

该领域唯一的“圣经”是可以某种方式测量的东西,如数据结构和算法,以及规范。我不会打扰鲍勃和马丁福勒叔叔之间更正确关于在哪里放置你的界面:把它放在你感觉舒适的地方以及适合你的地方。过了一段时间,如果你做出了错误的决定,你将始终能够重构和移动。