Home » Java Design Pattern » Single Responsibility Principle

Single Responsibility Principle

Single responsibility principle states that a class or a component must change for only one reason. So what is this change, what is the responsibility and what does it mean for a developer world and architects?

What is this change?

A change is any change or modification in software requirements. That means either a new functionality is added or existing functionality of the software components is modified or extended to meet the business needs.

What is responsibility?

A responsibility is the ownership of performing a task or set of related tasks.Consider a scenario where a class was designed to perform multiple tasks that handles three different features as shown below.

Before applying SRP


This class is also dependent on another class and components. During the development cycle they decided to enhance feature A. This enhancement requires changing the methodA of the class. Here if you are noticing as only one feature of the class has changed but there is potential risk of breaking the other feature or causing the bug. This may also lead to unnecessary testing of other tasks and dependent classes. The entire functionality handled in this class may also be required to be tested to ensure that everything is working fine. So in the above scenario we may need to test FeatureB and FeatureC also. This class has three reasons to change and it violates the principle.

What does it mean for a developer and Architect?

As you are aware, any enhancement or functional change in an existing app requires code changes. The complexity at which the code can be modified depends entirely on how the classes have been designed and coded. The more responsibility the class can perform , the more difficult it gets to get changes done.

Now the class1 of the above example is splitted into three classes as shown below.

after applying SRP


Now the changed architecture has a separate class for each independent feature. Now each class has only one reason to change. To avoid maintenance pitfalls it is always better to keep your classes simple and assigned to only one responsibility.

Single Responsibility Principle Example

The definition of the Single Responsibility Principle is simple i.e. one class has one responsibility and it should have only one reason to change. But in reality, designs go in the bad direction. Lets see an example to understand. Take a look at the Employee class below –

public class Employee{
  private String employeeId;
  private String name;
  private string address;
  private Date dateOfJoining;
  public boolean isConfirmed(){
    //employment status implementation
  }

  public Double calculateCurrentMonthSalary(){
    //current month salary logic implementation
  }


  public Double calcIncomeTaxForCurrentYear(){
    //income tax logic implementation
  }
  //Getters & Setters for all the private attributes
}

The above Employee class looks logically correct. It has all the employee attributes like employeeId, name, age, address & dateOfJoining. It also tells you if the employee is confirmed, the salary for the current month and calculates the income tax he has to pay for the year. If you closely look into the class it breaks the Single Responsibility Principle which is mentioned below.

  • The logic of determining whether the employee is a confirmed employee or not is actually not a responsibility which the employee owns. The company’s HR department owns this responsibility based on the company’s HR policies which may change every few years. On any such change in HR policies, the Employee class will need to be updated as it currently has the responsibility of a confirmed employee check.
  • Monthly salary calculation is not a responsibility of the Employee. It is the finance department’s responsibility to take care of the current month's salary.
  • Similarly, income tax calculation is not a responsibility of the Employee. It is the finance department’s responsibility to take care of the current tax structure which may get updated every year. If the Employee class owns the income tax calculation responsibility, then whenever tax structure/calculations change, the Employee class will need to be changed.
  • Lastly, the Employee class should have the single responsibility of maintaining core attributes of an employee.

Let's refactor the code to make a "good" design using SRP?

According to this principle, we need to separate out HR and Finance department functionality and its responsibility should be entirely encapsulated by the class. Below is an example to demonstrate the Single Responsibility Principle.

after applying SRP


Refactoring the Employee class so that it adheres to Single Responsibility Principle.

Let us now refactor the Employee class to make it our own responsibility.

Lets move the employee confirmation determination logic from Employee class to the HROperation class like this –

HROperation.java

public class HROperation{
  public boolean isConfirmed(Employee emp){
    //confirmation logic implementation using the employee information passed.
}
}

Similarly, lets move the income tax calculation logic from Employee class to FinanceOperation class –

FinanceOperation.java

public class FinanceOperation{
  public Double calcIncomeTaxForCurrentYear(Employee emp){
    //income tax logic implementation using the employee information passed
  }
}

Now Our refactored Employee class has a single responsibility of maintaining core employee functionality –

Employee.java

public class Employee{
  private String employeeId;
  private String name;
  private string address;
  private Date dateOfJoining;
  //Getters & Setters for all the private attributes
}


Conclusion

This tutorial explained what is Single Responsibility Principle with an example.

Previous Next Article

comments powered by Disqus