Dependency inversion principle

From CSSEMediaWiki
(Difference between revisions)
Jump to: navigation, search
Line 1: Line 1:
As stated by [[Bob Martin]]:
+
Often we would like to be able to reuse high level modules because they provide some general functionality which fits closely with some new problem we are trying to solve.  The problem is that often these high level modules depend a great deal on the lower level modules they make use of.  In this situation, what we need is an interface between the high and low level modules.  Both the high and low level modules are then written to depend upon this interface, and so they do not depend upon one another.  This allows us to interchange and reuse both the high and low level modules in a variety of situations.
 +
 
 +
[[Bob Martin]] observed this effect and stated the following to summarize the Dependency Inversion Principle (DIP):
 
:''"High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions."''
 
:''"High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions."''
  
The Dependency inversion principle states that high level modules should not depend on low level modules; both (high and low level) modules should depend on abstractions.
+
In OO design, the DIP is usually realized by a design similar to that depicted in the following diagram:
  
It is common in software development to write some low level modules that provide some useful functionality. These modules are then used by the high level modules. This means that the high level modules depend on the low level modules. The Dependency inversion principle states that both high and low level modules should depend on the same, general abstractions, thus inverting the dependency direction.
+
[[Image: Dependancy Inversion Principle.jpg]]
  
An advantage of this is that hard to simulate low level functions do not need to be written before high level functions are tested. This allows for a top-down approach for design and development.
+
In this situation the high and low level modules are classes, and the interface between these classes is provided by the two abstract class they inherit from.  The ConcreteHighLevel class only depends upon the AbstractLowLevel class, and the ConcreteLowLevel class only depends upon the AbstractHighLevel class.  So we can alter or add to the low level behavior by simply using a new ConcreteLowLevel class, and the ConcreteHighLevel class will be unaffected. From a different perspective, this means we can reuse the ConcreteHighLevel class so long as we provide a new ConcreteLowLevel class which conforms to the AbstractLowLevel interface and depends only on the AbstractHighLevel interface.
  
[[Image: Dependancy Inversion Principle.jpg]]
+
An additional advantage of following the DIP is that the hard to simulate low level functions do not need to be written before high level functions are tested. This allows for a top-down approach to design and development.
  
 
=== Typical Example ===
 
=== Typical Example ===

Revision as of 03:51, 17 July 2009

Often we would like to be able to reuse high level modules because they provide some general functionality which fits closely with some new problem we are trying to solve. The problem is that often these high level modules depend a great deal on the lower level modules they make use of. In this situation, what we need is an interface between the high and low level modules. Both the high and low level modules are then written to depend upon this interface, and so they do not depend upon one another. This allows us to interchange and reuse both the high and low level modules in a variety of situations.

Bob Martin observed this effect and stated the following to summarize the Dependency Inversion Principle (DIP):

"High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions."

In OO design, the DIP is usually realized by a design similar to that depicted in the following diagram:

Dependancy Inversion Principle.jpg

In this situation the high and low level modules are classes, and the interface between these classes is provided by the two abstract class they inherit from. The ConcreteHighLevel class only depends upon the AbstractLowLevel class, and the ConcreteLowLevel class only depends upon the AbstractHighLevel class. So we can alter or add to the low level behavior by simply using a new ConcreteLowLevel class, and the ConcreteHighLevel class will be unaffected. From a different perspective, this means we can reuse the ConcreteHighLevel class so long as we provide a new ConcreteLowLevel class which conforms to the AbstractLowLevel interface and depends only on the AbstractHighLevel interface.

An additional advantage of following the DIP is that the hard to simulate low level functions do not need to be written before high level functions are tested. This allows for a top-down approach to design and development.

Typical Example

File "Streams": Both high and low level code is written to meet the "stream" interface.

See Also

Personal tools