Single Responsibility Principle

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:

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:

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.