code-patterns
Code patterns & craft
Code is read far more than it is written. Learn the craft that keeps a codebase changeable — naming, SOLID, code smells, and safe refactoring — plus the judgment to know when an abstraction earns its keep.
Start track → 00
What good code is
Code is read and changed far more than it is written, so the dominant cost of software is the cost of change. 'Good code' is not an aesthetic — it is code whose next change is cheap. This unit installs that lens. 01
Names & intention
A name compresses intent. Good names reveal what and why, not how — and the difficulty of naming something is design feedback about whether it does one thing. 02
Functions & cohesion
A function should do one thing at one level of abstraction, separate commands from queries, and keep its arguments and side effects few and visible. Cohesion is the goal; small is a side effect. 03
Comments & contracts
Comments rot because they aren't executed; prefer code that documents itself and push invariants into types and tests, which can't lie. The few comments worth keeping explain why, not what. 04
SRP: single responsibility
A module should have one reason to change — be answerable to one actor — not literally do one thing. Group code by who requests changes; both god-class and class-explosion are SRP failures. 05
Open/Closed & Liskov
Add behaviour by adding code, not editing tested code (OCP) — but only along the variation axis you can predict. Subtypes must honour their supertype's contract so substitution never surprises a caller (LSP). 06
ISP & Dependency Inversion
Keep interfaces narrow so no client depends on methods it doesn't use (ISP), and make high-level policy depend on abstractions it owns rather than on low-level detail (DIP). Ports, adapters, and DI are the mechanics. 07
Coupling & cohesion, deep
Coupling has a measurable taxonomy (connascence): refactor toward weaker, more local coupling. The Law of Demeter and feature-based module boundaries confine the blast radius of change. 08
Smells: bloaters
Bloater smells — long methods, large classes, primitive obsession, data clumps — are cohesion decay you fix by extraction and value objects. Divergent change and shotgun surgery are the SRP smells you read off the git history. 09
Smells: couplers & dispensables
Coupler and dispensable smells — feature envy, message chains, middle men, dead code, speculative generality, type switches — bind or bloat code. Move behaviour to its data, delete the unused, and replace growing switches with polymorphism. 10
Refactoring: the safety net
You can't refactor safely without a net. Characterization tests pin current behaviour, seams get stubborn code under test, and the catalogue of small moves is applied one tiny step at a time under green. 11
Refactoring: larger moves
Larger refactorings — extract class, replace conditional with polymorphism, introduce parameter object — restructure design under green tests; patterns are destinations you refactor toward when the code demands them, not templates imposed up front. 12
Heuristics & tradeoffs
DRY, KISS, and YAGNI are heuristics that conflict, and judgment is choosing which dominates. The rule of three resists premature abstraction, because duplication is far cheaper than the wrong abstraction. 13
Anti-patterns & technical debt
God objects and anemic domains are structural anti-patterns to balance against; technical debt is real but financeable — make it visible, take it prudently, and pay it down via the boy-scout rule in code you already touch. 14
Capstone: refactor a messy module
Put it together on a realistic messy module: inventory the smells, refactor incrementally under characterization tests, and measure that the next change got cheaper — closing the loop back to the cost-of-change lens.React patterns, senior
You can already build with React — now learn the patterns seniors reach for: composition, state architecture, the server/client boundary, Suspense, and the anti-patterns to refactor away, so components stay simple as they scale.