Definition:
One should “Depend upon Abstractions. Do not depend upon concretions". Dependency Inversion Principle states,
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstractions should not depend on details. Details should depend on abstractions.
Description:
This help us to decouple the software modules. We will be achiving loosely couple code by decoupling these software modules. Thus high-level modules independent of the low-level module implementation details.
Example for DIP Vialoation:
IExport : an interface for Export operation.
WeeklyPlanner : Class with ExportWeeklyPlanner method, responsible for creating instance based on ExportFormat type and invoke Export method.
ExportAsPdf : Classs implements IExport interface, which can have code for PDF generation.
ExportAsExcel : Classs implements IExport interface, which can have code for EXCEL generation.
class DipViolation { private static void Main(string[] args) { WeeklyPlanner weeklyPlanner = new WeeklyPlanner(); weeklyPlanner.ExportWeeklyPlanner("This week plan for my wife", ExportFormat.Pdf); Console.ReadLine(); } } internal interface IExport { void Export(string toExport); } public class WeeklyPlanner { public void ExportWeeklyPlanner(string toExport, ExportFormat exportFormat) { IExport export = null; if(exportFormat == ExportFormat.Pdf) { export = new ExportAsPdf(); } else { export = new ExportAsExcel(); } export.Export(toExport); } } public class ExportAsPdf : IExport { public void Export(string toExport) { Console.Write("Weekly plan is exported in Pdf format"); } } public class ExportAsExcel : IExport { public void Export(string toExport) { Console.Write("Weekly plan is exported in Excel format"); } }
Where is the violation ?
WeeklyPlanner class have the object instantiaion for ExportAsPdf and ExportAsExcel classes. since WeeklyPlanner class(high level module) is depends on ExportAsPdf or ExportAsExcel classes(low level module). This violates Dependency Inversion Principle.
Fix for DIP Vialoation:
IExport : an interface for Export operation.
WeeklyPlanner : Class with ExportWeeklyPlanner method, with Export method. The object instantiation is removed from ExportWeeklyPlanner method and ExportWeeklyPlanner method has exportType parameter, which has IExport type.
ExportAsPdf : Classs implements IExport interface, which can have code for PDF generation
ExportAsExcel : Classs implements IExport interface, which can have code for EXCEL generation
Dip : The client class decides, which instance needs to be created like ExportAsPdf or ExportAsExcel
class Dip { private static void Main(string[] args) void Main(string[] args) { WeeklyPlanner weeklyPlanner = new WeeklyPlanner(new ExportAsPdf()); weeklyPlanner.ExportWeeklyPlanner("This week plan for my wife"); Console.ReadLine(); } } public interface IExport { void Export(string toExport); } public class WeeklyPlanner { private IExport exportType; public WeeklyPlanner(IExport exportType) { this.exportType = exportType; } public void ExportWeeklyPlanner(string toExport) { exportType.Export(toExport); } } public class ExportAsPdf : IExport { public void Export(string toExport) { Console.Write("Weekly plan is exported in Pdf format"); } } public class ExportAsExcel : IExport { public void Export(string toExport) { Console.Write("Weekly plan is exported in Excel format"); } }
The Export method in WeeklyPlanner class is invoked based on WeeklyPlanner constructor parameter. The instantiation of ExportAsPdf and ExportAsExcel is moved from ExportWeeklyPlanner method to Dip class. Thus, high level module WeeklyPlanner class does not have the object instantiation logic in ExportWeeklyPlanner class and instantiation logic is moved to client module(Dip class).