Single Responsibility Principle (S)
- sumitnagle
- Jun 22
- 3 min read
The Single Responsibility Principle (SRP) is the first and arguably most foundational principle from the famous SOLID principles of object-oriented design. SRP states that,
A class should have one and only one reason to change, meaning that a class (or module) should have only one job and should focus on a single responsibility or functionality.
In simpler terms, every module, class, or function should be responsible for doing a single well-defined task. If a class has more than one responsibility, it becomes coupled to multiple areas of the system, and changes in one part might inadvertently affect other parts. This makes code harder to understand, test, maintain, and extend.
For example, if a class handles both data persistence and business logic, a change in database structure would force a change in that class, even though the business logic remains untouched. This violates SRP.
We will first see why this below implementation is a bad implementation, imagine an Employee class that calculates pay, saves itself to a database, and formats its own details for a report.
/* single-responsibility violation */
class Employee {
private String name;
private Double salary;
public Pay calculatePay() { ... }
public void saveToDatabase() { ... }
public String generateReport() { ... }
}The Employee class is responsible for, business logic (pay calculation), data access, and reporting. A change in database structure or reporting format would require modifying the Employee class, risking side effects on salary calculation (and vice versa). To fix this, we separate concerns into different classes, each with a single-responsibility.
/* single-responsibility Compliance */
class Employee {
private String name;
private double salary;
}
class PayrollService {
public Pay calculatePay(Employee employee) { ... }
}
class EmployeeRepository {
public void saveToDatabase(Employee employee) { ... }
}
class EmployeeReportService {
public String generateReport(Employee employee) { ... }
}Now each class has one clear purpose (i.e. each class have separating concerns), PayrollService deals only with pay calculation, EmployeeRepository with persistence, and so on. A change in how we calculate pay affects only PayrollService.
In a typical Java web application (for example, a Spring Boot project), single-responsibility is seen in the layered architecture, controllers handle HTTP requests, services contain business logic, and repositories (or DAOs) handle database interactions. Spring Boot naturally encourages small, focused components (such as, separate service and repository classes), which naturally adhere to single-responsibility.
Let’s have a discussion about how to approach a problem with single-responsibility in mind.
When you face a new problem or feature requirement, start by clarifying "what distinct responsibilities exist within it". Think of responsibility as a reason for a part of your code to change. Whenever you read a requirement or start thinking about implementation, mentally parse it into "what actions need to happen", and "why they might need to change independently in the future".
For example, suppose you're asked to build a system that reads a file, parses its content, transforms the data, and then saves it to a database. At first glance, it might feel tempting to throw all that into one service or class, it’s convenient, you’re on a roll, and it works. But before doing that, pause and ask yourself,
What are the different tasks happening here? Could changes in one part affect others unnecessarily? If a business rule changes tomorrow, which part would be impacted?
From here, break down the tasks by their reasons to change. Reading a file might change if the file format changes. Parsing might change if the schema changes. Data transformation might change if business logic is updated. Database saving might change if the storage backend switches.
Once you identify these distinct areas, model them as separate classes or components. Even if these classes are small, that's perfectly fine. In fact, small classes that do one thing well are a healthy sign of SRP adherence.