Single Responsibility
Definition

Violation Example
// BAD: Multiple responsibilities - multiple reasons to change
public class Employee {
private String name;
private double salary;
// Responsibility 1: HR - employee data management
public void setName(String name) { this.name = name; }
public String getName() { return name; }
// Responsibility 2: Accounting - payroll calculations
public double calculatePay() {
// Complex tax calculations
// Different rules for different employee types
return salary * 0.8; // After tax
}
// Responsibility 3: IT/Reporting - data persistence
public void saveToDatabase() {
// SQL queries, connection handling
// Database-specific code
}
// Responsibility 4: IT/Reporting - report generation
public String generateReport() {
// Formatting, layout
// Report-specific logic
return "Employee Report: " + name;
}
}
// Problems:
// - Tax law changes → modify this class
// - Database schema changes → modify this class
// - Report format changes → modify this class
// - HR policy changes → modify this class
// All unrelated changes in one place!
Proper Implementation
// GOOD: Each class has one responsibility
// Responsibility: Employee data (HR stakeholder)
public class Employee {
private String id;
private String name;
private EmployeeType type;
public Employee(String id, String name, EmployeeType type) {
this.id = id;
this.name = name;
this.type = type;
}
// Only getters/setters for employee data
public String getId() { return id; }
public String getName() { return name; }
public EmployeeType getType() { return type; }
}
// Responsibility: Pay calculations (Accounting stakeholder)
public class PayrollCalculator {
private TaxService taxService;
public PayrollCalculator(TaxService taxService) {
this.taxService = taxService;
}
public Money calculatePay(Employee employee, PayPeriod period) {
Money grossPay = calculateGrossPay(employee, period);
Money taxes = taxService.calculateTaxes(grossPay, employee);
return grossPay.subtract(taxes);
}
private Money calculateGrossPay(Employee employee, PayPeriod period) {
// Pay calculation logic
}
}
// Responsibility: Persistence (IT/DBA stakeholder)
public class EmployeeRepository {
private DataSource dataSource;
public void save(Employee employee) {
// Database persistence logic
}
public Employee findById(String id) {
// Database query logic
}
}
// Responsibility: Report generation (Reporting stakeholder)
public class EmployeeReportGenerator {
public Report generate(Employee employee, ReportFormat format) {
// Report formatting logic
}
}
Service-Level SRP

Signs of SRP Violation

Applying SRP Correctly

Tips & Tricks
