Appendix

The Canon

Books worth knowing. Steel sharpens steel. Don't reinvent the wheel.

Label this appendix correctly before you use it: personal doctrine. Elsewhere this book insists there are no best practices, only tradeoffs. This is not the exception. It is one engineer's defaults, kept because they have paid for themselves in my contexts. Read certainty here as "my default," not "the answer."


The Books

These shaped how I think about software. Read them. Re-read them.

Design & Architecture

Practical Object-Oriented Design in Ruby by Sandi Metz (2012, 2nd ed. 2018) The clearest articulation of OO design principles. Language is Ruby, lessons are universal. Where "Sandi Metz's Rules" come from. Read this first if you write OO code.

A Philosophy of Software Design by John Ousterhout (2018) Complexity is the enemy. Deep modules beat shallow ones. Strategic vs. tactical programming. Short, opinionated, worth revisiting yearly.

Design Patterns by Gang of Four (1994) The shared vocabulary. You don't use all of them. You need to recognize all of them. Reference, not cover-to-cover.

Domain-Driven Design by Eric Evans (2003) For complex domains. Ubiquitous language. Bounded contexts. Aggregates. Heavy but essential when the domain is the hard part.

Testing

Test Driven Development: By Example by Kent Beck (2002) The original. Red-Green-Refactor. Money example is worth working through by hand.

Growing Object-Oriented Software, Guided by Tests by Freeman & Pryce (2009) Outside-in TDD. Mockist style. Start from the user-facing behavior, work inward. The walking skeleton. This is how I test.

xUnit Test Patterns by Gerard Meszaros (2007) Reference for test smells and patterns. Consult when tests become painful.

Refactoring

Refactoring by Martin Fowler (1999, 2nd ed. 2018) The catalog of refactorings. Name the moves. Small steps. Keep tests green. The discipline.

Working Effectively with Legacy Code by Michael Feathers (2004) When you inherit a mess. Characterization tests. Seams. How to get legacy code under test. Essential for real-world work.

Software Engineering

The Pragmatic Programmer by Hunt & Thomas (1999, 2nd ed. 2019) Foundational mindset. DRY. Orthogonality. Tracer bullets. Good defaults for how to think.

Clean Code by Robert Martin (2008) Contentious but useful. Take the naming and function size lessons. Leave the dogma.

Code Complete by Steve McConnell (1993, 2nd ed. 2004) Comprehensive. Dense. Construction-focused. Reference when you want the thorough answer.

Systems & Scale

Designing Data-Intensive Applications by Martin Kleppmann (2017) The modern systems book. Replication. Partitioning. Consistency. Stream processing. Required reading for backend engineers.

Release It! by Michael Nygard (2007, 2nd ed. 2018) Stability patterns. Bulkheads. Circuit breakers. Timeouts. How to build systems that survive production.

Site Reliability Engineering by Google (2016) SRE philosophy. Error budgets. Toil. Postmortems. The operational mindset.

Process & Teams

Extreme Programming Explained by Kent Beck (1999, 2nd ed. 2004) The XP values and practices. Pair programming. Continuous integration. Small releases. The source.

Accelerate by Forsgren, Humble, Kim (2018) The data on what makes teams effective. Lead time. Deployment frequency. Change failure rate. MTTR. Cite this when justifying practices.

The Phoenix Project by Kim, Behr, Spafford (2013) DevOps as narrative. The Three Ways. Good for convincing non-engineers.

Design (Visual)

Refactoring UI by Adam Wathan & Steve Schoger (2018) Practical visual design for developers. Hierarchy. Spacing. Typography. The cheat codes.

Don't Make Me Think by Steve Krug (2000, 3rd ed. 2014) Web usability fundamentals. Short, accessible, timeless. The first UX book every developer should read.

The Design of Everyday Things by Don Norman (1988, revised 2013) Foundational design thinking. Affordances, signifiers, feedback. Why doors confuse people. Shapes how you think about user interfaces.


The Reading Order

If you're starting from zero:

  1. Practical Object-Oriented Design in Ruby by Sandi Metz (2018)
  2. Test Driven Development: By Example by Kent Beck (2002)
  3. Refactoring by Martin Fowler (2018)
  4. Growing Object-Oriented Software, Guided by Tests by Freeman & Pryce (2009)
  5. A Philosophy of Software Design by John Ousterhout (2018)
  6. The Pragmatic Programmer by Hunt & Thomas (2019)
  7. Designing Data-Intensive Applications by Martin Kleppmann (2017)
  8. Working Effectively with Legacy Code by Michael Feathers (2004)
  9. Release It! by Michael Nygard (2018)

Read one. Apply it. Read the next. Don't rush.


This is a living document. Add to it as you learn. Steel sharpens steel.