Cheat sheet + 20 flashcards covering SOLID, DRY, KISS, YAGNI, coupling & cohesion, composition, and code smells.
A class should have only one reason to change. If a class handles both business logic and database access, a DB schema change forces you to touch business logic code.
Fix: split into separate classes — one for logic, one for persistence.
Open for extension, closed for modification. Add new behaviour by writing new code — not by editing existing, tested code.
Pattern: use Strategy, Decorator, or Plugin patterns so new variants slot in without touching the core.
A subtype must be substitutable for its base type without breaking the program.
Classic violation: Square extends Rectangle — setting width on a Square also changes height, breaking callers that expect independent dimensions.
Clients should not be forced to implement methods they don't use.
Split one large "fat" interface into many small, focused ones. A Printable class shouldn't also be forced to implement scan() and fax() it doesn't need.
High-level modules should not depend on low-level modules — both depend on abstractions.
Inject dependencies through interfaces. A OrderService depends on a PaymentGateway interface, not on StripePayment directly — swap providers without changing OrderService.
DRY: Don't Repeat Yourself — every piece of logic has one authoritative home. Duplication = two bugs to fix instead of one.
KISS: Keep It Simple — prefer the simplest working solution.
YAGNI: You Aren't Gonna Need It — build for today's requirements.
Coupling = degree to which modules depend on each other's internal details.
High coupling: changing module A breaks B, C, D.
Low coupling: modules are independent — change A without touching others.
Achieve with: interfaces, dependency injection, event systems.
Cohesion = how closely related a module's responsibilities are.
High cohesion: everything in the class serves one clear purpose — easy to understand and reuse.
Low cohesion: a "God class" doing many unrelated things — hard to change, test, or reuse parts of.
Favour has-a (composition) over is-a (inheritance).
Deep inheritance chains tightly couple children to parent — a change propagates everywhere. Composing small, focused objects is more flexible: swap a component without rewriting the hierarchy.
A method should only call methods on: itself, its parameters, objects it creates, or its direct fields.
Bad: a.getB().getC().doThing()
Good: a.doThing() — A handles the chain internally.
Long chains expose internal structure, creating fragile coupling.
Long Method: does too much — extract smaller functions
Large Class: too many responsibilities — split by SRP
Duplicate Code: extract to shared function (DRY)
Feature Envy: method uses another class's data more than its own
Primitive Obsession: use domain objects instead of raw strings/ints
Space flip · → next · ← prev · G got it · R review