Single Responsibility Principle (SRP)

Intent

There should be one and only one reason to change a particular class.

Description

We can define a responsibility of a class as a reason for change because a responsibility of a class is implied the implementation. The implementation may change in the future. If there is more than one reason to change the class, then that class has more than one responsibility. It violates the Single Responsibility Principle.

Examine the following class that represents an employee of an organization. We use C# as the programming language here.

Employee.cs

class Employee
{
string name;
int id;
double basicSalary;

//parameterized constructor
public Employee(string name, int id, double basic Salary)
{
this.name = name;
this.id = id;
this.basicSalary = basicSalary;
}

public double calculateSalary()
{
//business rule to calculate salary
}

public void save(FileStream fs)
{
//implementation
}

public void load(FileStream fs)
{
//implementation
}
}

This Employee class has methods for managing and operating the information of an employee and that is one responsibility of this class. It also has another responsibility to save the details of that particular employee in a file.

As the design perspective this Employee class violates the Single Responsibility Principle but it does not give compiler error or runtime error. It is just an inappropriate organization of classes of the application. Here the class has two axis of changes, one is the axis of employee information and its operations (calculateSalary() etc…) and the other is the persistence part (load(), save()). Therefore we need to change the class not only if the information and/or operations of the employee may change but also if the persistence part may change. Assume the client wants to save the employee information in a database. This would reflect a change to the existing code in Employee class. Other modules that depend on Employee class will also be affected and we have to retest, debug, and redeploy the module containing the Employee class.

Refactored Solution

We can separate these two responsibilities and put into two different classes as shown below. It may be much useful and easy to reflect any change to any class with a minimum effort.

Employee.cs

class Employee
{
string name;
int id;
double basicSalary;

//parameterized constructor
public Employee(string name, int id, double basic Salary)
{
this.name = name;
this.id = id;
this.basicSalary = basicSalary;
}

public double calculateSalary()
{
//business rule to calculate salary
}
}

Database.cs

class Database
{
public void save(Employee emp)
{
//implementation
}

public void load(Employee emp)
{
//implementation
}
}

Now it is possible to save the employee object in any kind of persistent storage without affecting the Employee class itself. Therefore only one axis of change remains for the Employee class. You can see Open-Closed Principle (OCP) as the next post. Stay tuned with us.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s