Dependency inversion principle

From Wikipedia, the free encyclopedia
Jump to: navigation, search

In object-oriented programming, the dependency inversion principle refers to a specific form of decoupling software modules. When following this principle, the conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are inverted (i.e. reversed), thus rendering high-level modules independent of the low-level module implementation details. The principle states

A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend on details. Details should depend on abstractions.

The principle inverts the way some people may think about object-oriented design, dictating that both high- and low-level objects must depend on the same abstraction.[1]


In conventional application architecture, lower-level components are designed to be consumed by higher-level components which enable increasingly complex systems to be built. In this composition, higher-level components depend directly upon lower-level components to achieve some task. This dependency upon lower-level components limits the reuse opportunities of the higher-level components.

The goal of the dependency inversion principle is to decouple application glue code from application logic. Reusing low-level components (application logic) becomes easier and maintainability is increased. This is facilitated by the separation of high-level components and low-level components into separate packages/libraries, where interfaces defining the behavior/services required by the high-level component are owned by, and exist within the high-level component's package. The implementation of the high-level component's interface by the low level component requires that the low-level component package depend upon the high-level component for compilation, thus inverting the conventional dependency relationship. Various patterns such as Plugin, Service Locator, or Dependency Injection are then employed to facilitate the run-time provisioning of the chosen low-level component implementation to the high-level component.

Applying the dependency inversion principle can also be seen as applying the Adapter pattern, i.e. the high-level class defines its own adapter interface which is the abstraction that the other high-level classes depend on. The adaptee implementation also depends on the adapter interface abstraction (of course, since it implements its interface) while it can be implemented by using code from within its own low-level module. The high-level has no dependency to the low-level module since it only uses the low-level indirectly through the adapter interface by invoking polymorphic methods to the interface which are implemented by the adaptee and its low-level module.

Figures 1 and 2 illustrate code with the same functionality, however in figure 2, an interface has been used to invert the dependency. The direction of dependency can be chosen to maximise code reuse, and eliminate cyclic dependencies.


In Eiffel, one can write a class with a feature called `keyboard: KEYBOARD'. Doing so places a rigid, fragile, and non-portable dependency between the Client class and its Supplier (i.e. KEYBOARD). To break the direct (i.e. rigid) dependency, we have at least two solutions. First, we can create an abstract ancestor of KEYBOARD such as READER. We then rename the feature from `keyboard: KEYBOARD' to `input_reader: READER'. Because KEYBOARD is a type of READER, we can substitute various forms of readers, including KEYBOARD. Notice that by changing from a more specific Supplier to a less specific (i.e. generic or abstract), we increase the number of potential Suppliers, making our code less rigid (many Suppliers), less fragile (will not break with the many Suppliers), and more portable. Finally, we can write our Client class with a Generic Parameter as in: MY_CLIENT [R -> READER], where the feature is now: `input_reader: R'.


The dependency inversion principle was postulated by Robert C. Martin and described in several publications including the paper Object Oriented Design Quality Metrics: an analysis of dependencies,[2] an article appearing in the C++ Report in May 1996 entitled The Dependency Inversion Principle,[3] and the books Agile Software Development, Principles, Patterns, and Practices, and Agile Principles, Patterns, and Practices in C#.

See also[edit]


  1. ^ Freeman, Eric; Freeman, Elisabeth; Kathy, Sierra; Bert, Bates (2004). Hendrickson, Mike; Loukides, Mike, eds. "Head First Design Patterns" (paperback) 1. O'REILLY. ISBN 978-0-596-00712-6. Retrieved 2012-06-21. 
  2. ^ Object Oriented Design Quality Metrics: an analysis of dependencies Robert C. Martin, C++ Report, Sept/Oct 1995
  3. ^ The Dependency Inversion Principle, Robert C. Martin, C++ Report, May 1996

External links[edit]