What does the Single Responsibility Principle (the "S" in SOLID) state, and what does "one reason to change" actually mean?
answer
- one reason to change = one actor
- not "do one thing", not line count
- Employee: pay / hours / save = 3 actors
- accidental coupling via shared private helper
- git history reveals the real seams
basics
~20 sSRP says a class or module should do one job, so only one kind of change forces you to edit it. If both a reporting change and a tax-rule change hit the same class, it has two responsibilities.
solid answer
~40 sSRP, the "S" of SOLID, says a module should have exactly one reason to change. Robert C. Martin later sharpened "reason" to mean one actor: a stakeholder or role whose requests cause that module to be modified. It is a principle about change and ownership, not about counting methods or lines. A class that computes payroll, formats a payslip document, and writes rows to a database serves finance, design/ops, and the DBA respectively — three actors, three reasons to change, so an SRP violation. The payoff: edits requested by one group cannot break behavior another group depends on, merge conflicts drop, and each piece is testable with fewer collaborators. The cost: more types and more wiring, so SRP is applied where change actually arrives, not uniformly everywhere.
go deeper
State the definition, give the pay/report/save example, and say the benefit is smaller, safer changes and easier tests.
Reframe "reason to change" as "actor", show the accidental-coupling failure mode via a shared private helper, and distinguish SRP from DRY and ISP.
Discuss how you locate seams empirically (commit history, change coupling), the cost of over-splitting, and how SRP interacts with cohesion metrics and facades that preserve a convenient call site.
Scale the argument: SRP at module and service granularity equals bounded contexts and team ownership (Conway's law); argue about organizational cost of a boundary, and when a coarse module deliberately owned by one team beats a "correct" split.
## The principle **SOLID** is a mnemonic for five object-oriented design principles popularized by Robert C. Martin. The **S** is the **Single Responsibility Principle (SRP)**. Classic phrasing: **"A class should have only one reason to change."** ## What "reason to change" means A *reason to change* is not a feature and not a method — it is a **source of change requests**. Martin's later refinement makes this explicit: > A module should be responsible to one, and only one, **actor**. An **actor** is a person or role who can ask for the software to behave differently: the finance department, the compliance officer, the DBA, the mobile team, an external API owner. Two actors pointing at the same class means two independent streams of edits arriving at the same file. ### Worked example (the canonical one) Imagine a class `Employee` with three methods: - `calculatePay()` — rules owned by **finance/accounting** - `reportHours()` — rules owned by **HR / operations** - `save()` — schema and persistence owned by the **DBA** Three actors, one class. This violates SRP. The danger is not aesthetic. Suppose `calculatePay()` and `reportHours()` share a private helper `regularHours()`. Finance asks for a tweak to overtime rounding; a developer edits `regularHours()`; HR's reports silently change. Nobody tested HR's path because nobody knew it was coupled. That is the failure mode SRP exists to prevent: **an accidental coupling between two independent change streams**. ## What SRP is NOT - **Not "a class should do only one thing."** That reading pushes people to one-method classes and an explosion of tiny types. "One thing" is undefined at any given zoom level: "handle checkout" is one thing; so is "append a byte". - **Not a size rule.** A 500-line class serving one actor can be fine; a 30-line class serving three actors is not. - **Not the same as the Interface Segregation Principle (ISP).** ISP is about not forcing *clients* to depend on methods they do not use; SRP is about not forcing *one module* to answer to multiple change sources. They often co-occur but are different principles. - **Not DRY.** DRY says do not duplicate knowledge. SRP sometimes tells you to *duplicate* a small helper so two actors do not share it. ## Why it pays off 1. **Change isolation** — a request from one actor touches one place; regression blast radius shrinks. 2. **Testability** — fewer collaborators to construct or fake, so tests are faster and more focused. 3. **Merge friction** — two teams stop editing the same file simultaneously. 4. **Comprehension** — you can name the class honestly; a name with "And" or "Manager" in it is a smell. ## Costs and limits Splitting introduces more classes, more injection/wiring, more indirection, and more navigation cost when reading. Over-applied, SRP produces "anemic" designs where logic is smeared thin across many one-line collaborators and no single file explains the behavior. The judgment call is empirical: **split along the seams where change has actually arrived (or is credibly forecast)**, not along every conceivable seam. Version-control history is the cheapest evidence — if a file appears in commits from three unrelated feature streams, that is your seam. ## Level of application SRP is stated for classes but scales: functions, classes, modules, packages, deployable services. At service scale it is the same idea as a **bounded context** in Domain-Driven Design — a boundary owned by one team/one language of the business. Applying SRP to services badly (one service per entity) is a classic distributed-monolith mistake.
- How do you find a class's actors when the requirements document does not list them?Read version-control history: group past commits touching the file by the feature stream or requester behind them. Distinct recurring streams are distinct actors. Also look at who reviews changes to the file and which tests break when it changes.
- Does SRP mean every class should have exactly one public method?No. A class can expose many methods as long as they all serve the same actor and change together. Cohesion, not method count, is the test.
A Swiss Army knife has many blades, but only one owner deciding what goes on it. SRP is about the owner, not the blades: if the corkscrew is chosen by the sommelier, the saw by the carpenter, and the scissors by the tailor, every redesign risks breaking someone else's blade.