Skip to main content

Tamilarasu Muthuswamy

Mastering the Single Responsibility Principle (SRP)

Introduction

Have you seen classes that try to do everything—validate input, calculate business rules, talk to databases, format output, and send notifications? They look convenient at first, but they become fragile, hard to test, and scary to change.

The Single Responsibility Principle (SRP) helps you fight that entropy: a class (or module/function) should have only one reason to change. In practice, that means each unit focuses on a single concern.


The Housekeeping Analogy

Think of a household:

  • One person tries to cook, clean, shop, fix appliances, manage bills, and babysit. They’re overworked; a delay or mistake in one area cascades into others.

  • Contrast that with clear roles: a cook, a cleaner, a shopper, and a handyman. Each role has a single responsibility; if a recipe changes, only the cook adapts. If the vacuum breaks, only the handyman acts.

That’s SRP: separate roles so each change has a single owner.


Why SRP Matters

  • Local change → One change touches one place.

  • Testability → Small units are easier to unit-test and mock.

  • Reusability → Focused classes are portable.

  • Parallel work → Teams can modify different responsibilities safely.


When to Use SRP (Signals & Triggers)

Use SRP when you notice any of these smells:

  • A class changes for multiple reasons (UI, rules, persistence, messaging).

  • Methods cluster around different concerns (validation vs. persistence).

  • Testing requires heavy setup because the class talks to everything.

  • Features are blocked because one giant class is a hotspot for merge conflicts.


Where to Apply SRP (Common Layers)

  • Domain/Model → Keep domain logic (e.g., Invoice.calculateTotal) free from printing, persistence, and transport concerns.

  • Application/Service → Orchestrate use cases: call domain logic, repositories, and notifiers—but don’t do their work.

  • Infrastructure → Repositories, HTTP clients, message publishers—keep I/O details out of the domain.

  • Presentation → Controllers/handlers map requests ↔ DTOs; avoid business rules here.


How to Apply SRP (Refactoring Steps)

  1. Identify responsibilities in a “God class”.

  2. Name the concerns (e.g., Calculation, Persistence, Printing, Notification).

  3. Extract classes so each owns exactly one concern.

  4. Define interfaces where useful (e.g., InvoiceRepository).

  5. Inject dependencies (constructor injection) rather than looking them up.

  6. Write focused tests per responsibility.


Java Example: SRP Violation (Before)

public class Invoice {
    // does calculation, printing, and saving
}
  • Changes in calculation, printing, or persistence all affect this class.


Java Example: SRP Applied (After)

public class Invoice { /* calculation only */ }
public class InvoicePrinter { /* printing responsibility */ }
public class InvoiceRepository { /* persistence responsibility */ }

  • Now each class has one responsibility.


Orchestration Example

public class InvoiceService {
    private final InvoiceRepository repo;
    private final InvoicePrinter printer;

    public String process(Invoice invoice) {
        repo.save(invoice);            // persistence
        return printer.print(invoice); // presentation
    }
}

The service coordinates responsibilities but doesn’t absorb them.


Don’t Overdo It

🚫 Overdone SRP: splitting a simple number into InvoiceAmount, InvoiceData, InvoiceCalculator classes.

Balanced SRP: keep data and calculation in Invoice, and delegate persistence/printing to separate classes.


When Not to Use SRP

  • Tiny scripts/prototypes where speed matters more than structure.

  • High‑cohesion utilities (e.g., a Money object doing arithmetic + formatting).

  • Performance‑critical paths where indirection is too costly.

  • Stable legacy code—extract gradually, not all at once.


Quick Checklist for Code Reviews

  • Can I describe this class in one sentence without “and/also”?

  • Will it change for more than one reason?

  • Are business rules mixed with persistence/UI?

  • Do tests require unrelated setup?

  • Can I localize a new change to one class?


Closing Thoughts

Just like a household runs smoother with clear roles, codebases thrive when each class owns one responsibility. Apply SRP where it clarifies intent and isolates change. Avoid the trap of over‑splitting; aim for cohesive, testable, and understandable units.

Mantra: One class, one reason to change.

Popular posts from this blog

What is a Web Application?

A web application is a program designed to perform some task for the user by getting information from a remote computer/server and delivered over internet through a browser or other apps. A Web app can be accessed from different mediums. Browser Based A browser based application is a web site which has some logical functionality for the user that is done on browser and or server and display results.   These types of applications need not to install. The only thing need is browser, which will display the data or information by a web page with the help of HTML, CSS and JavaScript using internet. Data can be retrieved from the server or locally. Sometimes we confuse all website is a web application. This is wrong, all websites is not a web application. A website which has some logical functionality will consider as a web application. We cannot tell static pages of the web site as a web application. Client Based A web application can run without browser help. These ...

Web Application Development

    Two things require for a web app development. That is front-end and back-end development. Front-end development      The Front end of a web application is a process get and display information and interact with user. Its main focus is how to design well, so that the page looks good and which helps to interact with user.     The front-end uses markup language to display information. Markup Language      Markup language that display text and formatting it in some order so the user can read it easily. It does not do any logic or calculation here only displaying text. Markup language have tags like keywords which can be used for formatting and we can also use any-word to form a tag and give definition for formatting. Tag always start with less-than symbol and grater-than symbol. eg: <html>,<xml>, <table>,<user>, etc... The three mainly using markup language are HTML,XML and XHTML. When we deve...

© 2025 Tamilarasu. All rights reserved.