Dependency Inversion Principle explained with simple example

Dependency Inversion Principle (DIP) is a software design principle which states that “High-level modules should not depend on low-level modules. Both should depend on abstractions And Abstractions should not depend on details. Details should depend on abstractions“. This design principle ensures a lower coupling between different classes.

Before going ahead we should know why do we need software design principle and what is software design principle.

Dependency Inversion Principle advantages:

  • Low coupling between classes.
  • Easy to debug.
  • Since higher modules are not dependent on lower modules which ensures higher flexibility.
  • Easily testable code as new changes in any module doesn’t break other module codes.

Let’s understand Dependency Inversion Principle with a simple example:

Consider an example of normal software company hierarchy

// Sample code. Syntax not verified
class developer
{
	public:
		virtual void work ()
		{
			// Write code
		}
};

class architect
{
	public:
		virtual void work ()
		{
			// Design code
		}
};

class tester
{
	public:
		virtual void work ()
		{
			// Test code
		}
};

class manager
{
	public:
		virtual void work ()
		{
			// manage employees
		}
		
		void addDeveloper (developer *d)
		{
			// Add developer
		}

		void addArchitect (architect *a)
		{
			// Add architect
		}

		void addTester (tester *t)
		{
			// Add tester
		}
};

Above class looks like doing the job well done but let’s analyse above classes from DIP perspective.

  • High level class “manager” has all info about it’s subordinate classes, means no Abstraction.
  • If we have to add a new class “teamLead” into the system then “manager” class also needs to be modified.
  • Unit test needs to be modified as “manager” class is changed.

Above points are violation of Dependency Inversion principle which states that “High level modules should not depend on low level modules“.

Let’s redesign the class keeping Dependency Inversion principle in mind.

// Sample code. Syntax not verified
class employee
{
	public:
		virtual void work () = 0;
};

class developer:public employee
{
	public:
		virtual void work ()
		{
			// Write code
		}
};

class architect:public employee
{
	public:
		virtual void work ()
		{
			// Design code
		}
};

class tester:public employee
{
	public:
		virtual void work ()
		{
			// Test code
		}
};

class manager:public employee
{
	public:
		virtual void work ()
		{
			// manage employees
		}
		
		void addEmployee (employee *e)
		{
			// Add employee
		}

};

Let’s analyse above classes from Dependency Inversion principle perspective.

  • class “manager” doesn’t know about its subordinate class, Abstraction holds.
  • If a new class “teamLead” added into system then high level class “manager” doesn’t need any change.
  • Since, no changes being done in “manager” class, hence no retest needs to be done on the older codes.

Above points ensures that Dependency Inversion principle is being followed.

Leave a Reply

Your email address will not be published. Required fields are marked *