The Dependency Inversion Principle
- 15 Aug, 2015
This is the sixth and final in a series of (hopefully) amusing posts into Robert Martin’s SOLID principles. It’s written as a dialog between Socrates and a student named Loej in the spirit of the dialectic method popularized by Plato. In this post, the principle explored is the “Dependency Inversion Principle”. I hope you find this enjoyable.
Socrates, who is the narrator of the dialogue.
Loej, who is but novice at the master’s feet.
Socrates: Here we are then. Do you recall what we discussed last time?
Loej: Yes the interface segregation principle.
Socrates: And what did this principle encourage?
Loej: It encourages dividing up interfaces so that, in general, each client gets its own interface.
Socrates: Very good. Today we discuss the last of Robert Martin’s SOLID principle, the Dependency Inversion principle.
Loej: I think he must be quite avuncular for giving us all this insight.
Socrates: Indeed. Anyway, the dependency inversion principle is perhaps the most counterintuitive of all of the SOLID principles.
Loej: Yeah it sounds like standing on your head while coding.
Socrates: Making the comprehension curve steeper is that this principle has taken on a life of its own. It has become a focal point for advocates of dependency injection and inversion of control containers. But these are not fundamental to the idea of dependency inversion.
Loej: So what is dependency inversion?
Socrates: According to Robert Martin, dependency inversion is a two part concept. First, high level modules should not depend upon low level modules. Rather, both should depend upon abstractions. Second, abstractions should not depend on details. Details should depend upon abstractions.
Loej: Wait please. One brain overload at a time. What is a high level module?
Socrates: Well, at the time Robert Martin’s original SOLID articles were written, a software movement called Structured Analysis and Design was becoming entrenched in software development.
Loej: You do realize that abbreviates to SAD.
Socrates: Indeed, and it was a bit sad. At that time we lost site of the code.
Loej: How so?
Socrates: Senior software staff were encouraged to stop coding and start architecting. Their job consisted of diagramming software processes at a high level and then exploding them into lower levels. In SAD, high level modules were defined by lower level modules ad nauseam. Abstractions were cut into pieces until defined by the gritty details.
Loej: Isn’t that what we have been taught by schools and almost all books? Haven’t we all been taught to think of software as smushing small bits into classes to create abstractions?
Socrates: Yes and we need to understand programming at that level, the concrete implementation level. But many of us stop when we can create an abstracted program from concrete parts. This is a natural stopping point, because this is the first time the code “works”.
Loej: But if it works, it works, right?
Socrates: What you really mean is that it works right now. Are you familiar with Ward Cunningham’s concept of technical debt?
Loej: You mean the second mortgage I took on my house to buy an MSDN Ultimate subscription?
Socrates: It’s the future pain we accrue with interest for doing things quick and dirty now. Have you ever cut corners for speed when a deadline was looming?
Loej: Sure. I think we all have.
Socrates: What usually happens?
Loej: We wind up having more defects or more trouble making changes down the rode.
Socrates: That’s technical debt, and unfortunately sometimes our frameworks encourage it. The last time you had to change your code to accommodate a new framework technology, what was it like?
Loej: It was like pulling weeds throughout the entire codebase.
Socrates: What if instead of composing classes from framework bits you composed them from abstractions?
Loej: Sure, but at some point you have to tie into the specifics.
Socrates: But you choose how and where you tie into the specifics. Can you strive to avoid having abstractions take unreasonable dependencies?
Loej: Sometimes the framework or specific technology dictates it though.
Socrates: True enough. Martin Fowler presented the idea of code smells when looking at target code for refactoring. I propose a similar idea when considering using a new .NET framework technology – a framework taste.
Loej: You’ve got to be kidding.
Socrates: I’m not. Do you like diet soda?
Loej: Sure. It was an acquired taste though.
Socrates: Diet soda tastes good after the first sip but leaves a bad aftertaste. You can get used to that though if you stick at it.
Loej: What does this have to to with .NET?
Socrates: Many .NET framework technologies are like that diet soda. They demo well but you know fundamentally it’s pretty nasty stuff. Still, if you stick with it, no matter how bad it is, you learn to love it.
Loej: That’s kind of funny.
Socrates: Now how about a fine Scotch? What did it taste like when you were a kid?
Loej: Horrible. Like a shag carpet
Socrates: Exactly. It was too complex a flavor. You had to grow into the nuances. Unlike the soda, you didn’t lean to tolerate it, you learned to appreciate it with maturity. Good framework technologies are like that.
Loej: I think we’ve totally lost site of dependency inversion.
Socrates: What I am getting at is that some technologies encourage SOLID principles and minimize technical debt. They help you fall into the “pit of success” Others heap on the technical debt with each new line of code. In regards to the dependency inversion principle, look for technology and patterns that helps you minimize dependencies and help you build self defining abstractions.
Loej: Well this has all certainly been insightful. Thank you master!
Socrates: Indeed. I hope you have found the SOLID principles a good starting point for thinking about software design. Until next time, remember to keep your code SOLID!