依赖反转原则

在面向对象编程领域中，依赖反转原则（Dependency inversion principle, DIP）是指一种特定的解耦（传统的依赖关系建立在高层次上，而具体的策略设置则应用在低层次的模块上）形式，使得高层次的模块不依赖于低层次的模块的实现细节，依赖关系被颠倒（反转），从而使得低层次模块依赖于高层次模块的需求抽象。

该原则规定：
 高层次的模块不应该依赖于低层次的模块，两者都应该依赖于抽象接口。
 抽象接口不应该依赖于具体实现。而具体实现则应该依赖于抽象接口。

该原则颠倒了一部分人对于面向对象设计的认识方式。如高层次和低层次对象都应该依赖于相同的抽象接口。


描述
在传统的应用架构中，低层次的组件设计用于被高层次的组件使用，这一点提供了逐步的构建一个复杂系统的可能。在这种结构下，高层次的组件直接依赖于低层次的组件去实现一些任务。这种对于低层次组件的依赖限制了高层次组件被重用的可行性。

依赖反转原则的目的是把高层次组件从对低层次组件的依赖中解耦出来，这样使得重用不同层级的组件实现变得可能。把高层组件和低层组件划分到不同的包/库（在这些包/库中拥有定义了高层组件所必须的行为和服务的接口，并且存在高层组件的包）中的方式促进了这种解耦。由于低层组件是对高层组件接口的具体实现，因此低层组件包的编译是依赖于高层组件的，这颠倒了传统的依赖关系。众多的设计模式，比如插件，服务定位器或者依赖注入，则被用来在运行时把指定的低层组件实现提供给高层组件。

应用依赖反转原则同样被认为是应用了适配器模式，例如：高层的类定义了它自己的适配器接口（高层类所依赖的抽象接口）。被适配的对象同样依赖于适配器接口的抽象（这是当然的，因为它实现了这个接口），同时它的实现则可以使用它自身所在低层模块的代码。通过这种方式，高层组件则不依赖于低层组件，因为它（高层组件）仅间接的通过调用适配器接口多态方法使用了低层组件，而这些多态方法则是由被适配对象以及它的低层模块所实现的。

另一個例子是檯燈和按鈕的例子 。

历史
依赖反转原则由提出，并且在数篇公开著作中被表述，包括论文《面向对象设计质量标准：对于依赖的分析》，以及一篇1996年出现在C++报道中的名为《依赖反转原则》的文章，和《敏捷软件开发，原则，模式和实践》，《C#中的敏捷原则，模式和实践》两本书。

参见
 适配器模式
 依赖注入
 接口
 控制反转
 插件
 服务定位器模式
 SOLID - “SOLID”中的 D 指代了依赖反转原则

引用

外部链接
 Object Oriented Design Quality Metrics: an analysis of dependencies Robert C. Martin, C++ Report, Sept/Oct 1995 
 The Dependency Inversion Principle, Robert C. Martin, C++ Report, May 1996
 Examining the Dependency Inversion Principle, Derek Greer

Category:软件设计模式
Category:软件设计
Category:编程原则
Category:面向对象的程序设计