Definition:
Class should have only one reason to change.
Description:
Responsibility can be reffered as "a reason for change". If a class have more than one reason to change, then the class have more then one responsibility.
Let us consider, we are in the process of developing Meal Planner application and shall consider the examples based on Meal Planner application development.
Example for SRP Vialoation:
Meal : Class is having AddMeal() and GetMealInformation() methods, are responsible for handing data operations. ExportMealInformation(string toExport) method is responsible for handling I/O file operation, exporting the meal information into file.
WeeklyPlanner : Class is having AddMealInWeekDay() and GetWeeklyMealInformation() methods, are responsible for handing data operations. ExportWeeklyMealInformation(string toExport) method is responsible for handling I/O file operation, exporting the weekly meal information into file.
// Class with Data & I/O File responsibilities public class Meal { // Data operation public void AddMeal() { Console.WriteLine("Meal is added into repository"); } // Data operation public string GetMealInformation() { Console.WriteLine("Fetch meal information from repository"); return "Meal information"; } // I/O File operation public void ExportMealInformation(string toExport) { Console.WriteLine("Export " + toExport + " into excel using OLEDB provider"); } } // Class with Data & I/O File responsibilities public class WeeklyPlanner { // Data operation public void AddMealInWeekDay(Meal meal) { Console.WriteLine("Meal is added into weekday"); } // Data operation public string GetWeeklyMealInformation() { Console.WriteLine("Fetch weekly meal information from repository"); return "Weekly meal information"; } // I/O File operation public void ExportWeeklyMealInformation(string toExport) { Console.WriteLine("Export " + toExport + " into excel using OLEDB provider"); } } class SrpViolation { static void Main(string[] args) { var meal = new Meal(); meal.AddMeal(); string mealInfo = meal.GetMealInformation(); var weeklyPlanner = new WeeklyPlanner(); weeklyPlanner.AddMealInWeekDay(meal); string weeklyPlanInfo = weeklyPlanner.GetWeeklyMealInformation(); meal.ExportMealInformation(mealInfo); weeklyPlanner.ExportWeeklyMealInformation(weeklyPlanInfo); Console.ReadLine(); } }
Where is the violation ?
Meal and WeeklyPlanner classes are having data opeartions(responsibility:1) and I/O file operation(responsibility:2).These two responsbilities are facilitating two reason to change the class. Its vialoation of Single Responsibility Principle. We need to make changes in both Meal and WeeklyPlanner classes if we modify any data operaion or I/O file opeation.
Fix for SRP Vialoation:
Let us create Export class with ExportInformation(string toExport) method for handling export information and remove ExportInformation(string toExport) method from Meal and WeeklyPlanner classes.
Meal : Class is having AddMeal() and GetMealInformation() methods, are responsible for handing data operations.
WeeklyPlanner : Class is having AddMealInWeekDay() and GetWeeklyMealInformation() methods, are responsible for handing data operations.
Export : Class is having ExportInformation(string toExport) method for handling export information.
// Class with Data responsibilities public class Meal { public void AddMeal() { Console.WriteLine("Meal is added into repository"); } public string GetMealInformation() { Console.WriteLine("Fetch meal information from repository"); return "Meal information"; } } // Class with Data responsibilities public class WeeklyPlanner { public void AddMealInWeekDay(Meal meal) { Console.WriteLine("Meal is added into weekday"); } public string GetWeeklyMealInformation() { Console.WriteLine("Fetch weekly meal information from repository"); return "Weekly meal information"; } } // Class with I/O File responsibility public class Export { public void ExportInformation(string toExport) { Console.WriteLine("Export the " + toExport + " into excel using OLEDB provider"); } } public class Srp { private static void Main(string[] args) { //Data Operations are handled in Meal & WeeklyPlanner classes var meal = new Meal(); meal.AddMeal(); string mealInfo = meal.GetMealInformation(); var weeklyPlanner = new WeeklyPlanner(); weeklyPlanner.AddMealInWeekDay(meal); string weeklyInfo = weeklyPlanner.GetWeeklyMealInformation(); // I/O File Operation is handled in Export class var export = new Export(); export.ExportInformation(mealInfo); export.ExportInformation(weeklyInfo); Console.ReadLine(); } }
Meal and WeeklyPlanner classes are responsible for handing data operations and Export class is responsible for handling I/O file export operation. The future changes for data operation shall be handled in Meal and WeeklyPlanner classes and future changes for Export operation shall be handled in Export class. All these classes are having single responsibility and one reason to change.