Single Responsibility Principle Examples(4 use cases)
We see some of the real-time software products following the SRP rule.
Table of Contents
SRP examples
Here are some examples of Java code that follow the Single Responsibility Principle (SRP):
Product
A "Product" class that has only one responsibility of storing and exposing product data:
public class Product {
private String name;
private double price;
private String description;
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public String getDescription() {
return description;
}
// Other methods for setting product data
}
The Product
class has only one responsibility of storing and exposing product data. The class has a clear and well-defined purpose, and any changes related to managing or exposing product data will only affect this class.
This makes the code more maintainable and reduces the likelihood of unintended side effects.
Calculator
A Calculator
class that performs mathematical calculations:
public class Calculator {
public static double add(double num1, double num2) {
return num1 + num2;
}
public static double subtract(double num1, double num2) {
return num1 - num2;
}
public static double multiply(double num1, double num2) {
return num1 * num2;
}
public static double divide(double num1, double num2) {
return num1 / num2;
}
// Other mathematical functions
}
The Calculator
class has only one responsibility performing mathematical calculations. The class is not responsible for managing input/output or other functionality outside mathematical operations.
Limiting the class's responsibility makes maintaining and testing the code easier.
Database
A "Database" class that is responsible for managing database connections and executing queries:
public class Database {
private Connection conn;
public void connect() {
// Code to establish database connection
}
public void disconnect() {
// Code to close database connection
}
public ResultSet executeQuery(String query) {
// Code to execute database query
}
// Other methods for interacting with the database
}
The Database
class has only one responsibility managing database connections and executing queries. The class is not responsible for any other functionality outside of database management. By limiting the class's responsibility, it becomes easier to modify and test the code.
In each of these examples, the class has a single responsibility that is encapsulated within the class. This makes the code easier to understand, modify, and maintain.
All three examples demonstrate SRP by adhering to the principle that each class should have only one reason to change. This results in easier-to-read, understand, and maintain code, reducing the likelihood of bugs and errors.
Employee details
Here's another example of the Single Responsibility Principle (SRP) applied to a class representing an employee.
class Employee {
private String name;
private String email;
private double salary;
public Employee(String name, String email, double salary) {
this.name = name;
this.email = email;
this.salary = salary;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public double getSalary() {
return salary;
}
}
In this example, the Employee
class has a single responsibility: model an employee. It has three instance variables, name
, email
, and salary
, and three methods to retrieve the values of these variables. The class has no other responsibilities, such as calculating taxes, sending emails, or printing information.
By following SRP, the code is easier to understand and maintain. Suppose we needed to add additional functionality in the future, such as calculating taxes. In that case, we could create a new class for this responsibility rather than adding it to the existing Employee
class. This helps to keep the code organized and maintainable and reduces the risk of introducing bugs.
By refactoring the above Employee use-case with SRP.
Here's an example of the Employee
class following the Single Responsibility Principle (SRP) by separating the responsibilities of modelling an employee and calculating taxes:
class Employee {
private String name;
private String email;
private double salary;
public Employee(String name, String email, double salary) {
this.name = name;
this.email = email;
this.salary = salary;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public double getSalary() {
return salary;
}
}
class TaxCalculator {
public double calculateTax(Employee employee) {
// code to calculate tax based on salary
return employee.getSalary() * 0.1;
}
}
In this example, the Employee
class has a single responsibility: model an employee. It has three instance variables, name
, email
, and salary
, and three methods to retrieve the values of these variables. The TaxCalculator
class is responsible for calculating taxes based on an employee's salary.
Following SRP, the code is better organized, more maintainable and scalable. If we need to change how we model an employee, we only need to modify the Employee
class, and if we need to change how we calculate taxes, we only need to modify the TaxCalculator
class. This reduces the risk of introducing bugs and makes it easier to test individual components in isolation.
Gopi Gorantala Newsletter
Join the newsletter to receive the latest updates in your inbox.