26 Oct 2023
Examples of problems and their solutions addressed through the Single Responsibility Principle (SRP)
Example 1: Bloated Task Manager Class
Problem :
The TaskManager
class combines multiple responsibilities, including task management and saving tasks to a file. This violates the Single Responsibility Principle (SRP) as it makes the class less maintainable and harder to change. Any modification to one responsibility may affect the other.
class TaskManager:
- tasks
+ addTask()
+ removeTask()
+ listTasks()
+ saveTasksToFile()
Solution:
To adhere to SRP, we split the responsibilities into two separate classes. The TaskManager
remains responsible for task management (adding, removing, and listing tasks), while the new TaskFileSaver
class is responsible for saving tasks to a file. This separation allows for independent modifications to task management and file-saving logic, making the codebase more maintainable.
class TaskManager:
- tasks
+ addTask()
+ removeTask()
+ listTasks()
class TaskFileSaver:
- tasks
+ saveTasksToFile()
Example 2: Monolithic Customer Class
Problem :
The Customer
class is overloaded with various responsibilities, including order placement, invoice sending, address updates, and order history management. This violates SRP, making the class complex and difficult to maintain. Changes in one area may unintentionally impact others.
class Customer:
- name
- email
- address
- orders
+ placeOrder()
+ sendInvoice()
+ updateAddress()
+ viewOrderHistory()
Solution :
To follow SRP, we divide the responsibilities into separate classes. The Customer
class now manages only customer-related data and address updates. The OrderManager
class handles order placement and order history, while the InvoiceSender
class focuses solely on sending invoices. This separation allows each class to have a single responsibility, making it easier to maintain and extend.
class Customer:
- name
- email
- address
+ updateAddress()
class OrderManager:
- orders
+ placeOrder()
+ viewOrderHistory()
class InvoiceSender:
- orders
+ sendInvoice()
Example 3: Bloated Logger Class
Problem :
The Logger
class is responsible for setting the log file name and logging different types of messages (error, info, warning). This results in a class with multiple responsibilities, which violates SRP, leading to code that's challenging to modify and maintain.
class Logger:
- logFileName
+ setLogFileName()
+ logError()
+ logInfo()
+ logWarning()
Solution :
To apply SRP, we split the responsibilities into separate classes. The Logger
class retains the responsibility of setting the log file name. New classes, such as ErrorLogger
, InfoLogger
, and WarningLogger
, handle specific message types. This separation ensures that each class has a single responsibility, making it easier to manage and modify the logging process.
class Logger:
- logFileName
+ setLogFileName()
class ErrorLogger:
- logFileName
+ logError()
class InfoLogger:
- logFileName
+ logInfo()
class WarningLogger:
- logFileName
+ logWarning()
Example 4: Overloaded Product Class
Problem :
The Product
class is tasked with managing product details, including name, price, description, and customer reviews. This combination of responsibilities violates SRP, making the class complex and harder to maintain.
class Product:
- name
- price
- description
- reviews
+ setName()
+ setPrice()
+ setDescription()
+ addReview()
Solution :
To adhere to SRP, we divide the responsibilities into separate classes. The Product
class now manages only basic product information, such as name, price, and description. The new ReviewManager
class is responsible for handling customer reviews. This separation keeps each class focused on a single responsibility, making the codebase more modular and maintainable.
class Product:
- name
- price
- description
+ setName()
+ setPrice()
+ setDescription()
class ReviewManager:
- reviews
+ addReview()