SRP is almost always misquoted as "a class should do one thing." The precise version is sharper: a class should have one reason to change. A reason to change is a stakeholder — a DBA who alters the schema, a finance lead who reworks pricing, a marketing team that rewrites emails. When one class answers to three stakeholders, any of them can force an edit, and their changes collide in the same file.
Here is the God class interviewers see constantly:
class Order {
private List<Item> items;
double total() { /* pricing rules live here */ return 0; }
void save() {
// opens a JDBC connection and writes rows
}
void emailConfirmation() {
// builds SMTP message and sends it
}
}
Three unrelated forces — persistence, pricing, and notification — share one class. A tax
rule change, a database migration, and a new email template each reopen Order. Split it
so each responsibility owns its own class:
class Order {
List<Item> items; // just the data + invariants
}
class PricingService {
double total(Order order) { /* pricing rules */ return 0; }
}
class OrderRepository {
void save(Order order) { /* JDBC writes */ }
}
class Notifier {
void sendConfirmation(Order order) { /* SMTP */ }
}
Now the DBA edits OrderRepository, finance edits PricingService, and marketing edits
Notifier — no shared file, no merge conflicts, no accidental breakage. Say to the
interviewer: "I'm splitting this by reason-to-change, so persistence, pricing, and
notification each have one owner and one place to edit."