The Dependency Inversion Principle
The DIP (Dependency Inversion Principle) is a principle that is formed by the structure of both OCP (Open Close Principle) and LSP (Liskov Substitution Principle). OCP and LSP have various rules and practices, with all the structural implications of both, a structure is formed that can be generalized into a principle itself which is the DIP.
What is ‘Bad Design’?
First we need to define how to know if a design is bad or not. We all think different and some times when a programmer reviews a code form a peer is pretty common that they would have done it in a different way, for one of them maybe a design is bad but based on what criteria? Here are some points to decide if a design is bad or not:
- It is hard to change because every change affects too many other parts of the system. (Rigidity)
- When you make a change, unexpected parts of the system break. (Fragility)
- It is hard to reuse in another application because it cannot be disentangled from the current application. (Immobility)
DIP defines two rules:
- 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 the high level modules, is where the business models and policy decisions are. High level modules should not depend on low level modules because then if a low level modules changes, it will change the high level module and this modules can’t change just like that because they have all the important information and rules that the client needs. So the correct thing to do is that low level modules depend on high level ones, this way if a client makes a change then the important modules have no option but to change but everything will be alright because this are the modules that will define the logic and procedures.
When high level modules are independent from lower ones, they can be reused freely in many ways and that is the main goal we are trying to achieve with this principle.
In every well structured object-oriented architecture there are clearly-defined layers. This layers should not depend upon each other as many people think, because if you connect every layer to each other directly then all layers will depend on the changes of any of them, one change in one layer will cause them all to change. The way to implement layering is to connect the layers to abstractions of themselves. This way the layers depend on an abstract class and not the layer itself directly and you will not break all layers just by changing one of them.
DIP is necessary
DIP has many benefits for object-oriented technologies, its proper application is necessary for the creation of reusable frameworks and also really important for code to be prepared and easy to change. Also, since abstractions and details are all isolated from each other, the code is much easier to maintain.