Friday, January 20, 2012
Dependency Inversion Principle
In a recent project I have been working on, I've been learning a lot about the Dependency Inversion Principle. There were some places in our code base were Micah showed us how we were violating the DIP and showed us how to refactor. In short, the DIP states that no module should be dependent on a concrete class, but rather an abstraction. Violations of this principle are commonly seen in higher level modules depending on lower level modules, such as a UI depending on a Controller or Model. This means that the modules within the UI become coupled and are not able to be reused later. In our case, our UI layer was directly depended on the concrete implementation of our application classes. In order to adhere to the DIP, we needed to refactor so that our UI was not dependent on our application logic. This required that we build two abstractions. We built an abstraction for the application (called an Interactor) and an abstraction for the UI. The UI interface talks to the Interactor interface and the Interactor interface talks to the UI interface. This allows the UI to be decoupled from the application logic. So, in theory, we could build another implementation of the application underneath of the UI and the UI would be none the wiser. By the same token, we can now build any number of UI's on top of the application and the application is non the wiser. The second scenario is not really a theoretical possibility, but reality. There are tentative plans to build a web application on top of the current architecture (in addition to the desktop app we are building now). Without these abstractions, building the new Web UI would turn the code base into a tangled mess that no one could maintain. So, in summary, always program to an interface or abstraction, never a concrete class.