Dependency Inversion Principle (DIP) | SOLID PRINCIPLES

Dependency Inversion Principle (DIP) 

The Dependency Inversion Principle (DIP) states that high-level modules (e.g., business logic) should not depend on low-level modules (e.g., data access or specific implementations); both should depend on abstractions (e.g., interfaces or abstract classes). Additionally, abstractions should not depend on details; details should depend on abstractions. This principle helps to decouple components and make the system more flexible and maintainable.


Example:


Consider a scenario where a high-level module (`BusinessLogic`) depends directly on a low-level module (`DatabaseService`):



public class DatabaseService

{

    public void SaveData(string data)

    {

        // Code for saving data to a database

    }

}


public class BusinessLogic

{

    private readonly DatabaseService databaseService;


    public BusinessLogic(DatabaseService databaseService)

    {

        this.databaseService = databaseService;

    }


    public void ProcessData(string data)

    {

        // Business logic processing

        databaseService.SaveData(data);

    }

}


In this example, `BusinessLogic` is directly dependent on the `DatabaseService`, violating the Dependency Inversion Principle.


Adhering to DIP:


Refactor the code by introducing an interface (`IDataService`) and having both high-level and low-level modules depend on the abstraction:



public interface IDataService

{

    void SaveData(string data);

}


public class DatabaseService : IDataService

{

    public void SaveData(string data)

    {

        // Code for saving data to a database

    }

}


public class BusinessLogic

{

    private readonly IDataService dataService;


    public BusinessLogic(IDataService dataService)

    {

        this.dataService = dataService;

    }


    public void ProcessData(string data)

    {

        // Business logic processing

        dataService.SaveData(data);

    }

}



Now, both `BusinessLogic` and `DatabaseService` depend on the abstraction `IDataService`. This adheres to the Dependency Inversion Principle, allowing for easier substitution of implementations and reducing the coupling between modules.


Comments