Clean Code vs. A Philosophy Of Software Design
Meta: HN Culture & Downvotes
- Early subthread clarifies that “me too / great post” comments are downvoted because they add no information; downvotes are framed as disagreement or quality control, not “hate”.
Overall View: Clean Code vs. A Philosophy of Software Design (APoSD)
- Many commenters strongly prefer APoSD: call it pragmatic, concise, and grounded in experience with real systems and teaching; several say it was the first book that actually changed how they design code.
- Clean Code is described as useful early in a career (forcing people away from 5,000‑line functions and spaghetti) but harmful when taken literally: it encourages over‑decomposition, tiny functions, excessive indirection, and dogmatic rule‑following.
- Several say they “grew out of” Clean Code: it gave initial structure, then became a negative example of what not to do.
- Some criticize the claim that APoSD is the “only” evidence‑based book and point to empirical software engineering work and curated research (e.g., Greg Wilson, EMSE, “It Will Never Work in Theory”).
Dogma, Teaching Quality, and Career Impact
- Recurrent complaint: Clean Code is taught and treated as gospel for juniors, who then police codebases with reference to the book rather than context.
- Stories of teams derailed by “Uncle Bob devotees”: PRs dominated by style fights, deep abstraction layers over simple DB calls, low feature throughput, and morale issues.
- Others defend the material but blame misuse: strong, prescriptive rhetoric is seen as an intentional shock against 1990s‑era messes; good engineers are expected to apply judgment, not follow rules mechanically.
- A large subthread argues that as a teacher, Martin’s absolutist tone plus dated examples encourages rigidity in exactly the audience (intermediate‑seeking‑senior devs) that most needs nuance and context.
Comments, Naming, and the “Why”
- Very strong pushback on “comments are failures” and “code is more precise than English”:
- Comments are seen as essential for documenting why code is structured oddly (hardware quirks, library bugs, business constraints, performance hacks).
- Several note real‑world examples (USB drivers, flaky devices, vendor limitations) where behavior cannot be inferred from code alone; long method names cannot sensibly encode this.
- ADRs, external docs, and literate‑style comments are recommended; many observe that engineers ignore external docs but will read comments adjacent to code.
- Long, hyper‑descriptive method names are criticized: they hurt readability, still can’t capture “why”, and become misleading when circumstances change.
Function Length, Over‑Decomposition, and “Lasagna Code”
- Very common theme: tiny 2–4‑line functions lead to “lasagna”/“baklava” code—dozens of thin layers that only forward arguments or slightly reshuffle them.
- Debugging such code requires stepping through hundreds of stack frames to find where anything real happens.
- Some argue small functions can be excellent when composed purely (functional style, no shared mutable state); but most real OO code doesn’t meet those constraints.
- Several prefer larger, straight‑line functions (especially with IDE folding) over forests of micro‑methods, emphasizing cognitive load, locality, and ease of stepping through in a debugger.
Domain Modeling, DDD, and the Anemic Domain Model Debate
- Big, heated thread around “anemic domain model is an anti‑pattern”:
- Pro‑DDD side: domain objects should encapsulate behavior; anemic models are just DTOs and “not OO”; they “incur the cost of a domain model without benefits”.
- Counter‑arguments:
- Good software isn’t synonymous with OO; rich models can entangle unrelated concerns (Orders knowing about DBs, schedulers, email systems), violating single‑responsibility and increasing coupling.
- Many constraints inherently span multiple aggregates (monthly limits, cross‑entity rules), which are better enforced in services, repositories, or higher‑level “systems”, not on entities themselves.
- Natural language favors “an order is cancelled” (by some system), not “order.cancel()”.
- Several assert that “domain model” is not inherently OO; others insist it is. No consensus emerges; the disagreement is flagged as largely philosophical and contextual.
Type Systems, Tests, and TDD
- Some are surprised both books and the debate largely ignore modern static type systems; multiple commenters see strong types as a primary tool for safety, documentation, and refactorability.
- Others point out that when Martin wrote Clean Code, mainstream type systems and FP weren’t as widely adopted; now the pendulum has swung.
- Opinions on TDD/XP are split:
- Critics say TDD is heavyweight, focuses people on implementation details, and doesn’t help with non‑incremental design problems.
- Supporters argue small, safe steps and refactor phases can drive better design if practiced pragmatically.
Prime Number Example & Thread-Safety Issues
- The Clean Code prime generator example is widely attacked:
- Refactor into many tiny methods with long names is seen as making the algorithm harder to understand compared to a single well‑commented function.
- The ASCII “explanation” diagram is viewed as opaque and less helpful than a textual summary or a link to the underlying algorithm.
- A technical critique notes that Martin’s refactoring stores state in static fields, making it unsafe in multithreaded use and misleadingly named (helper methods with side effects).
- Several appreciate Ousterhout’s alternative: one comprehensible routine with rationale encoded in comments.
APoSD: Complexity, Abstraction, and Critiques
- Fans summarize APoSD’s key heuristic as: good abstractions hide more complexity than they introduce, with a rough “5–20:1” complexity‑to‑interface ratio as a useful rule of thumb.
- This is applied to questions like when to introduce interfaces, how many subclasses make a hierarchy worthwhile, and what’s an appropriate function size.
- One critic argues APoSD’s definition of “complexity” (“whatever makes the system hard to modify”) is subjective; contrasts it with a more structural view (“things twisted together”) and prefers books like The Practice of Programming.
- Despite criticism, many say APoSD’s framing—“separate what matters from what doesn’t, and hide the latter”—is more balanced and less absolutist than Clean Code.
Dogmatism, Context, and “Best Practices”
- Strong recurring theme: any rule (“short functions”, “no comments”, “always DDD/OO”, “TDD everywhere”) becomes harmful when detached from context.
- Commenters urge treating books as sources of heuristics, not law—especially given software’s variability (short‑lived MVPs vs. decades‑long systems, solo work vs. large teams, high‑performance vs. CRUD).
- Several note that much “best practice” in industry is fashion‑ and authority‑driven rather than evidence‑based, and that reading real, successful codebases (and seeing what survives quietly) may be more instructive than any single book.