Dependency inversion principle
Line 1: | Line 1: | ||
− | + | 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."'' | ||
− | + | In OO design, the DIP is usually realized by a design similar to that depicted in the following diagram: | |
− | + | [[Image: 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 === | === 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:
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.