Dependency inversion principle is a software design principle which
provides us the guidelines to write loosely coupled classes. According
to the
definition of Dependency inversion principle:
What does this definition mean? What is it trying to convey? let us try to understand the definition by looking at examples. A few years back I was involved in writing a windows service which was supposed to run on a Web server. The sole responsibility of this service was to log messages in event logs whenever there is some problem in the IIS application Pool. So what our team has done initially that we created two classes. One for monitoring the Application Pool and second to write the messages in the event log. Our classes looked like this:
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstractions should not depend upon details. Details should depend upon abstractions.
What does this definition mean? What is it trying to convey? let us try to understand the definition by looking at examples. A few years back I was involved in writing a windows service which was supposed to run on a Web server. The sole responsibility of this service was to log messages in event logs whenever there is some problem in the IIS application Pool. So what our team has done initially that we created two classes. One for monitoring the Application Pool and second to write the messages in the event log. Our classes looked like this:
class EventLogWriter { public void Write(string message) { //Write to event log here } } class AppPoolWatcher { // Handle to EventLog writer to write to the logs EventLogWriter writer = null; // This function will be called when the app pool has problem public void Notify(string message) { if (writer == null) { writer = new EventLogWriter(); } writer.Write(message); } }
From the first look, the above class design seems to be sufficient. It looks perfectly good code. But there is a problem in the above design. This design violates the dependency inversion principle. i.e. the high level moduleAppPoolWatcher
depends onEventLogWriter
which is a concrete class and not an abstraction. How is it a problem? Well let me tell you the next requirement we received for this service and the problem will become very clearly visible.The next requirement we received for this service was to send email to network administrator's email ID for some specific set of error. Now, how will we do that? One idea is to create a class for sending emails and keeping its handle in theAppPoolWatcher
but at any moment we will be using only one object eitherEventLogWriter
orEmailSender
.The problem will get even worse when we have more actions to take selectively, like sending SMS. Then we will have to have one more class whose instance will be kept inside theAppPoolWatcher
. The dependency inversion principle says that we need to decouple this system in such a way that the higher level modules i.e. theAppPoolWatcher
in our case will depend on a simple abstraction and will use it. This abstraction will in turn will be mapped to some concrete class which will perform the actual operation.
No comments:
Post a Comment