Resources
The books, talks and channels that have shaped my thinking, each with a note on why it’s worth your time. It’s a selective list rather than a comprehensive bibliography. Everything outside the reading list at the end is something I’ve read or watched and found genuinely useful.
Software Architecture
Section titled “Software Architecture”- “Screaming Architecture” — Robert C. Martin (2011). A short post with a lasting idea: the structure of a codebase should reveal what the system does, not which framework it’s built on.
- Patterns of Enterprise Application Architecture — Martin Fowler (2002). One of the books I value most. Many of the patterns I use day to day come from it, along with the choice between Transaction Script and Domain Model (see Application Design Patterns).
- Clean Architecture: A Craftsman’s Guide to Software Structure and Design — Robert C. Martin (2017). The clearest case I know for why the ability to change a system matters more than whether it works today (see Designing for Change).
- Domain-Driven Design: Tackling Complexity in the Heart of Software — Eric Evans (2003). The “blue book”. Bounded contexts, ubiquitous language and a rich domain model shape how I draw boundaries, from modules within an application to services across a system (see The Code Is the Model).
- Applying Domain-Driven Design and Patterns: With Examples in C# and .NET — Jimmy Nilsson (2006). A great companion to Evans’ “blue book”, with examples in C# and .NET that make the ideas concrete.
- Implementing Domain-Driven Design — Vaughn Vernon (2013). The “red book”, and another great companion to the blue book. Evans can be dry and academic; Vernon makes the ideas more concrete and approachable, with more prescriptive guidance. Written a decade later, it also reflects what the community learned about applying DDD in the meantime.
- Enterprise Integration Patterns — Gregor Hohpe and Bobby Woolf (2003). I read this back in my BizTalk days. It’s not a book I turn to day to day, but many of its patterns apply directly to technologies such as Azure Service Bus, and much of its terminology is still the common language of messaging (see System Design Patterns).
- Understanding Distributed Systems — Roberto Vitillo (2021). A deep dive into the principles and patterns of distributed systems design, covering scalability, resilience, testing and operations.
- Building Microservices: Designing Fine-Grained Systems — Sam Newman (2nd edition, 2021). Arguably the microservices book, covering the foundations as well as the technical and organisational challenges of a microservices architecture.
- Monolith to Microservices: Evolutionary Patterns to Transform Your Monolith — Sam Newman (2019). In-depth guidance on migrating from a monolith to microservices. Just as importantly, it covers when that migration is appropriate in the first place, and the growing pains that come with a microservices architecture.
- Kubernetes Patterns: Reusable Elements for Designing Cloud-Native Applications — Bilgin Ibryam and Roland Huß (2019). Covers the underlying principles and building blocks of Kubernetes, framed as design patterns. Rather than just describing each feature, it focuses on the problem the feature solves, which gives a real understanding of the “why” of Kubernetes.
Development
Section titled “Development”- Design Patterns: Elements of Reusable Object-Oriented Software — Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, the “Gang of Four” (1994). The seminal patterns book, and the one that put “favour composition over inheritance” on the map. The hype has faded, but the patterns remain a useful common language (see Application Design Patterns).
- A Philosophy of Software Design — John Ousterhout (2018). Tactical versus strategic programming: treating good design as a small, continuous investment rather than something to catch up on later (see Use the Compiler to Enforce Dependency Rules).
- Growing Object-Oriented Software, Guided by Tests — Steve Freeman and Nat Pryce (2009). The version of the walking skeleton I reach for (chapter 4, “Kick-Starting the Test-Driven Cycle”).
- Working Effectively with Legacy Code — Michael Feathers (2004). Not one I turn to day to day, but full of interesting techniques for getting a legacy codebase under test and changing it safely. The idea I’ve found most useful is the “seam”: a place where you can change a program’s behaviour without editing the code at that point, which gives you somewhere to break a dependency and get a test in.
Podcasts
Section titled “Podcasts”- .NET Rocks! — Carl Franklin and Richard Campbell. Probably the most popular and longest-running .NET podcast. Each show typically focuses on the views, experiences and latest projects of a leading voice in the .NET community.
- “TDD, Where Did It All Go Wrong” and “TDD Revisited” — Ian Cooper. Much of this matches my own experience. The point that stuck with me, paraphrasing: the trigger for writing a new test should be a new requirement or behaviour, not adding a new class or method.
YouTube
Section titled “YouTube”- Modern Software Engineering — Dave Farley. Strong, well-argued views on TDD, pair programming and continuous delivery, with development treated firmly as engineering rather than craft. I don’t always agree, but that’s part of the value: it’s a clear position to test my own views against. More recently, the channel has focused heavily on AI-assisted development, which makes it a useful lens on how those engineering practices hold up when an AI is writing much of the code.
- CodeOpinion — Derek Comartin. In-depth coverage of topics such as vertical slice architecture, event-driven architecture and microservices, with clear, pragmatic guidance throughout.
- Cosden Solutions — Useful, thorough coverage of React and front-end design patterns.
- Milan Jovanović — A well-produced, popular channel covering a wide range of topics, including Clean Architecture, DDD, design patterns and EF Core, with a focus on .NET and C#.
On My Reading List
Section titled “On My Reading List”Books I haven’t read yet. Most are the sources of ideas I already use and credit on this site.
- Building Evolutionary Architectures — Neal Ford, Rebecca Parsons and Patrick Kua (2017). The origin of fitness functions: automated checks that stop an architecture’s key characteristics eroding as the system changes.
- The Mythical Man-Month: Essays on Software Engineering — Fred Brooks (anniversary edition, 1995). Brooks’s Law, conceptual integrity and “Plan to Throw One Away” (cited in Early Solutions). This edition also includes Brooks’ essay “No Silver Bullet” (1986), the source of the split between essential and accidental complexity behind how I think about managing complexity.
- Lean Software Development: An Agile Toolkit — Mary and Tom Poppendieck (2003). Where the “last responsible moment” comes from: delay a decision until not deciding would close off an important option (see Avoid Paralysis by Analysis).
- Modern Software Engineering: Doing What Works to Build Better Software Faster — Dave Farley (2021). The book behind the YouTube channel above. I don’t always agree with the channel, which is exactly why I want to read the full argument and test my own views against it.
