Search Knowledge

© 2026 LIBREUNI PROJECT

Single Responsibility Principle (SRP)

Single Responsibility Principle (SRP)

The Single Responsibility Principle is the “S” in SOLID. It states that:

“A class should have one, and only one, reason to change.” — Robert C. Martin

What is a “Reason to Change”?

A “reason to change” is synonymous with a “responsibility”. If a class handles multiple disparate tasks, it has multiple responsibilities.

The Problem with Multiple Responsibilities

  1. Fragility: Changing one responsibility might accidentally break another.
  2. Low Cohesion: The class becomes bloated and hard to understand.
  3. Difficult Testing: You have to mock many unrelated things to test one function.

Example: The Multi-Purpose User Class

The Bad Way (Violating SRP)

This class handles user data, validation, and database saving.

class User:
    def __init__(self, username, email):
        self.username = username
        self.email = email

    def validate_email(self):
        return "@" in self.email

    def save_to_db(self):
        print(f"Saving {self.username} to database...")

If the database schema changes, we change the User class. If the validation logic changes, we change the User class. This class has two reasons to change.

The Good Way (Applying SRP)

We split the responsibilities into separate classes.

class User:
    def __init__(self, username, email):
        self.username = username
        self.email = email

class UserValidator:
    @staticmethod
    def validate(user):
        return "@" in user.email

class UserRepository:
    def save(self, user):
        print(f"Persisting {user.username} to DB...")

SRP in C++

Consider a class that manages a Report and also prints it.

// Violation
class Report {
    string content;
public:
    void generate() { /* ... */ }
    void print() { cout << content << endl; } // Printing logic mixed with data logic
};

// Fixed
class Report {
    string content;
public:
    string getContent() { return content; }
};

class ReportPrinter {
public:
    void print(Report& r) { cout << r.getContent() << endl; }
};

How to Identify SRP Violations

  • Size: Very large classes often have too many responsibilities.
  • Imports: A high number of imports from unrelated modules.
  • Documentation: If you find yourself using “and” to describe what a class does (e.g., “This class parses data AND sends emails”).
  • Frequent Changes: If different teams are constantly touching the same file for different reasons.

Benefits of SRP

  • Maintainability: Smaller classes are easier to read and modify.
  • Reusability: UserValidator can be reused in different parts of the app without bringing in the database logic.
  • Testability: Unit tests for UserValidator don’t need to know about databases.