In the last post I looked a bit at the Dependency Inversion Principle which says to define an interface representing the contract of a dependency that you need someone to fulfill for you. It's a really great technique for encouraging SRP and loose coupling.
The whole idea behind the DIP is that your class depends only on the interface, and doesn't know anything about the concrete class implementing that interface. It doesn't know what class it's using, nor does it know where that class came from. And thus, we gain what we were after: the high level class can be reused in nearly any context by providing it with different dependencies. And on top of that, we gain excellent separation of concerns, making our code base more flexible, more maintainable, and I'd argue more understandable. Clearly, the DIP is awesome!
But! I'm sure you were waiting for the But... Since we now have to provide our object with it's dependencies, we have to know:
- Every interface it depends on
- What instances we should provide
- How to create those instances
Fortunately, someone invented Inversion of Control Containers, so we don't have to create these objects ourselves. Or, maybe unfortunately, 'cause now we don't have to create these objects ourselves, which sweeps any unsavory design issues away where you wont see them...
What design issues? Well, the leaking of implementation details obviously! Are there others? Probably. Maybe class design issues with having too many dependencies? Or having dependencies that are too small and should be rolled into more abstract concepts? But neither of these is a result of injecting Inverted Interfaces, only the implementation leaking.
I do believe this is leaky, but I'm not really sure if it's a problem exactly. At the end of the day, we're really just designing a plugin system. We want code to be reusable, so we want to be able to dynamically specify what dependencies it uses. We're not forced to pass the dependencies in, we could use a service locator type approach. But this has downsides of it's own.
In the next post, I'll wrap this up by zooming back out and trying to tie this all together.