Most readers will be familiar with Bob Martin's famous dependency inversion principle, which states -

  1. High-level modules should not depend on low-level modules. Both should depend on abstractions

  2. Abstractions should not depend upon details. Details should depend upon abstractions

I believe I understand it all pretty well, except for the first sentence in the second line - "Abstractions should not depend upon details". What does this mean exactly? What would be a simple example of an abstraction being dependent upon a detail?

  • 1
    The definition of "abstraction" and "detail" should clarify this. What part of the definition of "abstraction" confuses you? Perhaps you could update the question to explain why the words are confusing. We're not you, so we don't know what part of this confuses you. – S.Lott Apr 4 '11 at 15:13

What he's saying here is that you should avoid a scenario where a base class takes a dependency to meet the need of a descendant. Let's look at the case of a Switch and its descendant the TimedSwitch. The TimedSwitch is a Switch that resets itself after a certain amount of time. We have the TimedObject class already so it would make sense for TimedSwitch to derive from it...however TimedSwitch already derives from Switch. So in order to meet the needs of the TimedSwitch, Switch will inherit from TimedObject even though it doesn't need that functionality itself.

The Switch (abstraction) is dependent on the details of TimedSwitch. To fix this violation of the DIP, we have TimedSwitch implement ITimedObject and delegate to a contained TimedObject class (prefer composition over inheritance).

Another more generic example is the layered approach. The higher level layers are abstractions and in most cases they depend on the details. DIP says that instead, the lower layers should conform to an interface which they both take dependency on. Thus the dependency is inverted from Higher Layer depending on lower layer to both layers depending on an interface.

| improve this answer | |
  • So where is the inversion in the layers example? I can only see new abstraction introduced with additional dependency on it. What exactly is inverted? – ᄂ ᄀ May 5 '13 at 12:33

The controller module uses the ControllableThing abstraction (interface) to control a Thing module.

A bad design would have the ControllableThing interface exposing the number of LED lights in the FizzBuzz corporation Thing the project was written for originally. setLed1(boolen state) setLed2(boolen state) setLed3(boolen state) setLed4(boolen state)

that sort of thing...

So now, both modules will break when we go to control a Nazbatag intelligent rabbit module.

The DI principle is really about getting the dependancy graph for the system to have very short paths from modules to interfaces.

When the abstractions are done right the systems won't break next week.

Judgement should be used, because the temptation to make generic interfaces leads things that look like SOAP and the Unix device model. A meta system can help if you're architecting systems of systems. There is a design force here pushing towards dynamic languages and call-time binding. It's not necessary or helpful to give in to it all the time.

| improve this answer | |
  • +1 Great footnote about using the right tool for the job. – jv42 Apr 4 '11 at 8:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.