Single Responsibility Principle

Nagaraju Swarna
3 min readApr 3, 2024

--

A class should have only one reason to change, means a class should do only one job or should have only one responsibility.

Let’s dive deeper into the Single Responsibility Principle (SRP) with a practical example. Consider a system for managing a library’s book inventory. A common violation of SRP occurs when a class takes on responsibilities that should be separated into different classes.

class LibraryBook:
def __init__(self, title, author, isbn):
self.title = title
self.author = author
self.isbn = isbn
self.location = None

def check_in(self, location):
self.location = location
# Logic to add the book back to the library inventory

def check_out(self):
self.location = 'Checked out'
# Logic to remove the book from the library inventory

def save(self):
# Logic to save the book details to a database

Above example is a violation of SRP Principle since it has multiple responsibilities, Checking-in the books(Inventory), persisting book data to a database, managing book properties. Refactoring above code adhering to SRP principle:

class LibraryBook:
def __init__(self, title, author, isbn):
self.title = title
self.author = author
self.isbn = isbn

class InventoryManager:
def __init__(self):
self.books = {} # Stores book ISBNs and their locations

def check_in(self, isbn, location):
self.books[isbn] = location
# Additional logic for adding the book back to inventory

def check_out(self, isbn):
self.books[isbn] = 'Checked out'
# Additional logic for removing the book from inventory

class BookPersistence:
def save_book(self, library_book):
# Logic to save the book details to a database
pass

def load_book(self, isbn):
# Logic to load book details from a database
pass

However, following the Single Responsibility Principle (SRP) often leads to a design with more classes, each handling a single responsibility. Applying SRP (and other design principles) requires balance. Over-segmentation can lead to an excessive number of classes, making the system overly complex and potentially difficult to navigate.

The key is to identify genuinely distinct responsibilities that justify separation into different classes. The goal is to enhance the maintainability, scalability, and understandability of the code without overcomplicating the design.

Therefore, while SRP often results in creating more classes, the principle should be applied judiciously to strike the right balance between simplicity and modularity.

In the Java Collections Framework, the principle of Single Responsibility is followed, ensuring that each class has one and only one reason to change. This principle is a key aspect of SOLID design principles, promoting a cleaner, more modular structure.

A clear example of the Single Responsibility Principle (SRP) in the Java Collections Framework is the distinction between the `List`, `Set`, and `Map` interfaces, each serving a distinct purpose:

List Interface: Represents an ordered collection of elements that can contain duplicate values. It is responsible for maintaining the insertion order of the elements, and it allows positional access and insertion of elements. Classes like `ArrayList` and `LinkedList` implement the `List` interface, each with a specific approach to data storage and access, but all adhering to the single responsibility of managing an ordered collection.

Set Interface: This represents a collection that cannot contain duplicate elements. It is designed for scenarios where uniqueness of the elements is crucial. Implementations of the `Set` interface, such as `HashSet` and `TreeSet`, ensure that no two elements in the collection are the same, adhering strictly to their single responsibility of managing a set of unique elements.

Map Interface: This represents a collection of key-value pairs, where each key is unique. This interface is responsible for associating unique keys to specific values, allowing for efficient retrieval, update, and deletion of entries based on the key. Classes like `HashMap` and `TreeMap` implement the `Map` interface, each ensuring that they adhere to the single responsibility of managing a collection of key-value pairs where keys are unique.

--

--

Nagaraju Swarna

Full Stack Engineer @ Aflac | Tech Enthusiast | Competitive Programmer