Dependency Inversion Principle And Interface

This is another one in the series of OOP design principles after Law Of Demeter.

A software design is made of objects and communication between them. Eventually it becomes a mesh of interdependencies between these objects, which combined with business constraints like money or time, drives bad software design.

Robert Martin (pdf) defines bad software design by its three basic attributes.

A piece of software that fulfills its requirements and yet exhibits any or all of the following three traits has a bad design:

  1. It is hard to change because every change affects too many parts of the system. (Rigidity)
  2. When you make a change, unexpected parts of the system break. (Fragility)
  3. It is hard to reuse in another application because it cannot be disentangled from the current application. (Immobility)

Whenever a functionality is implemented, it can be divided in the high level modules and low level modules. The high level modules are usually the representative of the concept of the activity, whereas the low level activities are the deatils of the high level module. e.g., the activity of logging (the high level module) can be divided into:

  • formation of message to be logged
  • write the message into a target destination

When implemented, the lower level modules can have specific code, like the module for writing the message might write to a flat file. Consider the following algorithm of the logging module:

form_message
write_message_to_file

Later when the logging has to happen to a database, the algorithm for logging module would have to change to:

form_message
write_message_to_database

Here, a change in the low level module has caused change in the high level module. This means that we cannot reuse the logging module without using the implementation of the low level module for writing the message.

Everything was fine at a conceptual level, the problems happened during implementation. Why not include the concept in the design itelf? This can be done by introducing abstractions. Consider the following algorithm:

logging:
    form_message
    write_message

write_message:
    write_message_to_disk

We have introduced a level of indirection here, the logging module does not communicate directly with the module for writing message to the disk. It talks to the module for writing message, which can keep all its implementation changes internal to itself. Now the logging module is independent of the implementation of writing the message, and can be reused by itself.

This is what the general formulation of the Dependency Inversion Principle states:

High level modules should not depend upon low level modules. Both should depend upon abstractions.

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

What this really means is that we have separated the concept and the implementation physically by introducing abstraction. This defines a very powerful rule for designing and programming: Design to an interface, not an implementation, i.e., a class that wants to log should be designed against the high-level module and not the low-level module.

This principle also is based on the advantage of loose coupling between objects, which makes the design more flexible and reusable.

Related Links:

Back to Design Principles.

Technorati tags: , , , , , ,

Copyright Abhijit Nadgouda.

Posted in design. 8 Comments »

8 Responses to “Dependency Inversion Principle And Interface”

  1. Abhijit Nadgouda @ iface » Blog Archive » Acyclic Dependencies Principle Says:

    […] Cyclic dependencies usually happen because multiple developers might work on the same package, on the same module or on the same class. These cyclick dependencies can be broken. One of the methods is to use Dependency Inversion Principle (DIP). Robert Martin has excellent illustration (pdf) of breaking the cyclic dependencies. […]

  2. Abhijit Nadgouda @ iface » Blog Archive » Design Principles Says:

    […] Dependency Inversion Principle And Interface (DIP) […]

  3. Abhijit Nadgouda @ iface » Blog Archive » Stable Dependencies Principle Says:

    […] This principle can go to an atomic level of classes and say that classes should depend on more stable classes only. This is a direct derivation of the Dependency Inversion Principle (DIP). […]

  4. Abhijit Nadgouda @ iface » Blog Archive » Stable Abstractions Principle Says:

    […] Applying the class design principles, especially the Dependency Inversion Principle (DIP), flexibility is built into a design by introducing abstract classes. Concrete classes depend on the abstract classes for reusability and extensibility. This directly drives that Packages that are maximally stable should be maximally abstract. Instable packages should be concrete. The abstraction of a package should be in proportion to its stability. […]

  5. Abhijit Nadgouda @ iface » Blog Archive » Simplification Using Abstraction Says:

    […] Let us consider an example. The modern banking involves multiple channels of accessing your account – in addition to physicall visiting the bank, you can use the internet banking and phone banking facilities. If you visit the bank, your account number is used to identify you and signature to authenticate. Similarly the combination of username/password and account number/pin number is used when using internet banking and phone banking respectively. Conceptually, these are just different ways of saying that the bank needs to identify you, the customer. This seems to be much simpler and time saving than specifying the details for understanding. When an additonal channel is required, say ATM machines, the process of identification will be still required, but can be carried out in a different way. It is not difficult to realise that again this can lead to a better reusability. I have said this before, the abstract levels really represent the concept or the idea. Abstraction decouples the purpose from the means of achieving it. Interface is a classic example. […]

  6. Qaiser Saeed Says:

    What is the difference between DIP and OCP they seem to be one and the same. IMHO DIP is a tool to achieve OCP. Is this correct?

  7. Abhijit Nadgouda Says:

    OCP is essentially about making one class flexible via extensibility rather than keeping it open for code modifications. DIP looks at establishing relationships between classes using loose coupling so that direct dependency is reduced. This results in easier maintenance.

    Overlap between the two is because both of them use abstraction.

  8. code::gallery :: Single, Double And Multiple Dispatch :: July :: 2006 Says:

    […] However, as you can see, the biggest disadvantage is that the base class Animal has to know all the derived classes. Everytime a new animal is added, the interface of Animal has to change making it impractical, exactly what the Dependency Inverstion Principle advises us to avoid. […]


Leave a comment