SOLID principles
beginnerSingle Responsibility Principle (SRP)
A class should have one, and only one, reason to change.
A class should have one job. That is the short version of SRP, and it is slightly wrong in a way that matters.
A restaurant kitchen: the chef cooks, the sommelier picks wine, the dishwasher cleans. One person doing all three serves customers slowly and badly.
Key Concepts
1
The real rule is about change: a class should have one reason to change. Put differently, it should
answer to one group of people.
2
An example. You have a class called OrderReport. It does three things:
OrderReport
3
calculateTotal() the finance team decides these rules
formatHtml() the design team decides how it looks
saveToDatabase() the platform team decides where data goes4
Three teams can each demand a change to this one file. A tax change, a redesign and a database migration
all land in the same place, and each one risks breaking the other two.
5
Split it into three classes and each team edits its own.
6
Why "one job" is a poor test. Is "handle orders" one job? Is "check the delivery address on an order"
one job? Both sound reasonable. The phrase gives you no way to decide, so people argue about it. "One
reason to change" gives you a question you can actually answer: who asks for this to change?
7
A check you can run on real code. Look at the fields in the class, then at which methods use them. If
half the methods use one set of fields and the other half use a completely different set, you have two
classes sharing a name. Splitting them is usually obvious once you look.
8
You can also go too far. Some people split until every class has one method. Then reading a single
piece of behaviour means opening fifteen files, and nothing is reusable. A long class that only one team
has touched in two years is usually fine. A short class that three teams keep editing is not.
9
What the interviewer is probing.1. "What is SRP?" Probing: whether you learned the phrase or the idea. Stalls: "A class should do
one thing." Moves up: one reason to change, one group it answers to — and why "one thing" cannot be
tested.
10
2. "Is this class breaking it?" Probing: whether you can apply it. Stalls: counting the methods.
Moves up: asking who can force a change, and checking whether the methods share fields.
11
3. "Can a 500-line class be fine?" Probing: size versus responsibility. Stalls: "No, it is too
big." Moves up: yes, if every part changes for the same reason. Length is a hint, not the rule.
12
4. "What goes wrong if you overdo it?" Probing: balance. Stalls: "Nothing." Moves up: tiny
classes that each do almost nothing, and one behaviour spread across fifteen files.
13
5. "How would you split this class?" Probing: method. Stalls: "By feature." Moves up: group by
who asks for changes, confirm with the field check, and keep the outside interface the same while you
move things.
14
Two masters, one class15
class OrderReport {
BigDecimal calculateTotal() // finance decides the rules
String formatHtml() // design decides the layout
void saveToDatabase() // platform decides storage
}16
Three actors. A tax change, a redesign and a schema migration all
edit the same file, and each risks the other two.17
Split by actor:
OrderCalculator -> finance
OrderRenderer -> design
OrderRepository -> platform18
The cohesion check19
fields: a, b, c, d
method1 uses a, b
method2 uses a, b
method3 uses c, d
method4 uses c, d
-> two clusters sharing no state: two classes in one.20
Over-application, what it looks like21
OrderService -> OrderValidator -> OrderValidationRule ->
OrderValidationRuleEvaluator -> ...22
Each class has one method that calls the next. Nothing is
reusable, nothing is independently testable in a meaningful
way, and reading one behaviour means opening the whole chain.23
A usable rule of thumb
Ask "who asks for this to change?" If the answers differ,
split. If they are the same, leave it -- even at 500 lines.