Managing Dependencies
A mentor of mine once told me that a key element of obejct-oriented-design (OOD) is dependency management. But let’s first see if we can understand what a depencdency is:
An unhealthy dependency is a situation where an object needs to know too much about another object in order to send meaningful messages to each other. The problem is that when two or more objects are so tightly coupled (CBO – coupling of objects) that they behave as a unit, it’s impossible to reuse just one.
Dependency injection to the rescue. Dependency injection relies on the technique of writing objects that are flexible enough to accept the injection of other objects in order to perform their tasks. To give you a real world example: If we had a car that would run on Shell fuel only, then our car object would be too rigid. A better car object is an object that runs on any fuel, no matter who produced it. As long as the fuel object burns according to the engine specs, the car should drive.
It is helpful to think of every dependency as a bacterium that you want to isolate. Just as society avoids and isolates dangerous people, dependencies should also be isolated.
The code below shows a method gear-inches that has an unhealthy dependency on wheel. The method should not have to know about wheel in order to be helpful.
# gear_inches depends on wheel def gear_inches ratio * wheel.diameter end def wheel @wheel || = Wheel.new(rim, tire) end
We can improve this situation by adding a diameter method that will be soley responsible to return the value of the diameter.
def gear_inches ratio * diameter end def wheel @wheel || = Wheel.new(rim, tire) end def diameter wheel.diameter end
What did we just do?
We effectively isolated the wheel dependency and therefore created a more flexible and controllable situation. This may seem very simple, but I wish I had understood this concept when I started coding my first apps. It helps to ask the following question over and over again: Does my method do more than it needs to do? Does my method know more than it needs to know. These litmus test questions are derived from the Single Responsibility Principle in OOD. This principle is not only applicable to classes, but also to its methods.
Note:
I am writing this educational blog post to solidify coding principles that are essential when writing software. The post is largely based on Sandi Metz’ excellent book Practical Object-Oriented Design in Ruby: An Agile Primer (Addison-Wesley Professional Ruby). I do not claim any credits for its ideas and outlined principles.