What Is the Single Responsibility Principle?

The Single Responsibility Principle (SRP) says:

A class should have only one responsibility, meaning one reason to change.

In plain words:

  • Each class should focus on one main job.

  • If a class is doing many different, unrelated things, it will be hard to change and easy to break.

Examples of mixed responsibilities:

  • A class that validates input, stores data in a database, and sends emails.

  • A class that calculates order totals and also generates PDF invoices.

  • A class that handles business rules and also logs to files.

SRP asks you to split these roles into separate classes, each focused on one concern.

Why SRP Matters in LLD

When a class does too much:

  • Changes ripple everywhere

    • Modifying one feature risks breaking another, because they are tangled in the same class.

  • Harder to understand

    • New developers struggle to see what the class is really “about”.

  • Harder to test

    • You can’t test one behavior without setting up unrelated things.

With SRP:

  • Each class is small and focused.

  • You can understand it by reading its name and a few methods.

  • Changes in one area (like logging) don’t force you to touch unrelated business logic.

In Low-Level Design, SRP helps you go from a big “god class” to a set of clean, cooperating components.

Example of a “God” Class Violating SRP

Imagine an OrderService that does everything:

This class has many responsibilities:

  1. Validation.

  2. Price calculation.

  3. Persistence (saving to database).

  4. Payment processing.

  5. Notification (email).

  6. Logging.

Any change in validation, payment logic, email format, or logging may force changes in OrderService.
It violates SRP.

Applying SRP: Splitting Responsibilities

Let’s split the above into focused classes.

Validation Responsibility


Price Calculation Responsibility


Persistence Responsibility


Payment Responsibility


Notification Responsibility


Logging Responsibility


Now, a slimmer OrderService that coordinates these single‑responsibility classes:


Now:

  • Each class does one thing well.

  • OrderService Orchestrates them but does not own all the detailed logic.

This is SRP in action.

How SRP Helps Testing and Changes

With SRP‑compliant design:

  • You can test PriceCalculator separately.

  • You can test OrderValidator with just a list of items.

  • You can mock or stub. PaymentProcessor 

  • If the email content changes, only NotificationService changes.

  • If you switch from console logs to file logs, only Logger changes.

Each change has a clear home.
You rarely need to touch many classes for a small feature or bug fix.

This significantly improves maintainability in real systems and demonstrates good design in interviews.

How to Spot SRP Violations

Watch for classes that:

  • Have method names across very different concerns (e.g., validate, saveToDb, sendEmail in the same class).

  • Depend on many unrelated collaborators (e.g., database, logger, email, SMS, cache, all injected into the same class).

  • Have names that are too generic (e.g., Manager, Helper, Processor) and seem to do “everything”.

Good practice:

  • Name classes by one clear role: OrderValidator, UserRepository, PaymentProcessor, InvoiceGenerator.

  • If a class name needs the word “and” to describe it (“PaymentAndNotificationManager”), that’s a red flag.

Summary

The Single Responsibility Principle states that each class should have one responsibility and therefore one reason to change.

You saw:

  • What does SRP mean in simple language?

  • Why “god classes” that do everything are problematic.

  • How to refactor such a class into multiple focused classes, each with one job.

  • How SRP improves readability, maintainability, and testability in LLD designs.

  • How to recognize SRP violations and rename/split classes to fix them.