Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Architecture

Pattern

A reusable solution you can apply to your work.

“Architecture is the decisions you wish you could get right early.” — Ralph Johnson

Context

Once a team (or an agent) knows what to build, the next question is how to organize the whole thing. Architecture operates at the architectural scale: the large-scale shape of a system, the choice of major components, the way data flows between them, and the reasoning behind those choices. It sits above the code but below the product strategy, bridging intent and implementation.

Architecture isn’t a diagram. It’s a set of constraints — some chosen, some inherited — that guide every decision downstream. A well-chosen architecture makes the common cases easy and the hard cases possible. A poorly chosen one makes everything hard.

Problem

How do you give a system a structure that survives contact with reality (changing requirements, growing teams, evolving technology) without over-engineering it from the start?

Forces

  • You need to make structural decisions before you have full information.
  • Changing architecture later is expensive, but guessing wrong early is also expensive.
  • Different parts of a system may need different styles (a batch pipeline and a real-time API have different concerns).
  • The architecture must be understandable not just to its creators but to everyone who will work on it, including AI agents.

Solution

Treat architecture as the set of decisions that are costly to reverse. Focus your early effort there and leave everything else flexible. Identify the key boundaries: where does the system end, where do its major parts divide, what crosses those lines? Choose patterns for communication: does data flow through a shared database, through APIs, through events? Document the why behind each choice, not just the what. A design doc that captures these decisions and their rationale pays for itself many times over.

Good architecture isn’t about picking the trendiest style. It’s about matching the structure to the forces at hand: the team’s size, the expected rate of change, the deployment constraints, and the nature of the domain. A small team building a single product may thrive with a monolith. A platform serving many consumers may need explicit interfaces and strict contracts.

In agentic workflows, architecture also determines how effectively an AI agent can navigate the codebase. Clear boundaries and well-defined modules give an agent a manageable scope. When every file depends on every other file, the agent has to load the entire codebase into its context window just to change one thing. That coupling is where mistakes come from.

How It Plays Out

A startup building a new web application chooses a three-layer architecture: a React frontend, a REST API, and a PostgreSQL database. Each layer talks only to its immediate neighbor. When the team later needs to add a mobile client, the API layer is already there and the mobile app becomes another consumer.

Agentic coding workflows reward explicit architecture. When you tell an agent “add a caching layer to the data access module,” the agent needs to know where that module lives, what it depends on, and what depends on it. If the architecture is documented and the boundaries are clear, the agent can make the change confidently. If the system is a tangle of implicit connections, even a capable agent will introduce regressions.

Tip

When working with AI agents, keep an architecture document (even a brief one) in the repository root. The agent can read it to orient itself before making changes.

Example Prompt

“Read the architecture document in docs/architecture.md. The system has three layers: React frontend, REST API, and PostgreSQL database. Add the caching feature to the data access layer without crossing into the API layer.”

Consequences

A clear architecture reduces the cognitive load on everyone who works on the system, human or agent. It makes decomposition possible by defining where the seams are. It constrains future choices, which is both its power and its cost: an architecture that’s too rigid will fight you when requirements shift, while one that’s too loose provides no guidance at all.

Architecture decisions tend to be self-reinforcing. Once you’ve chosen a layered style, new code flows into those layers. This helps when the architecture fits the problem and hurts when it doesn’t. Revisiting architecture periodically and asking “does this shape still serve us?” is one of the most valuable things a team can do.

  • Refines: Shape — architecture is the shape at the system level.
  • Uses: Component, Boundary, Interface — the building blocks of architectural decisions.
  • Enables: Decomposition, Separation of Concerns — architecture makes principled splitting possible.
  • Contrasts with: Monolith — a monolith is one particular architectural choice, not the absence of architecture.
  • Violated by: Big Ball of Mud – the absence of architecture produces an undifferentiated tangle.
  • Measured by: Coupling – the degree of connection between components reveals whether architectural boundaries are holding.
  • Related: Technical Debt – architectural debt is the most expensive kind.
  • Recorded by: Design Doc — the design doc records architectural decisions before they exist in code.

Sources

  • Dewayne Perry and Alexander Wolf defined the formal study of software architecture in “Foundations for the Study of Software Architecture” (1992), modeling it as elements, form, and rationale. Their paper established the vocabulary that let the field move from folklore to discipline.
  • Mary Shaw and David Garlan wrote Software Architecture: Perspectives on an Emerging Discipline (1996), the first comprehensive textbook on the subject. It catalogued architectural styles (pipes-and-filters, layered, event-driven) and gave practitioners a shared language for structural choices.
  • Martin Fowler’s “Who Needs an Architect?” (IEEE Software, 2003) reframed architecture as “the decisions that are hard to change” — the definition this article adopts. The column grew from an exchange with Ralph Johnson, whose epigraph quote appears above.
  • Ralph Johnson, co-author of Design Patterns (1994), argued on the Extreme Programming mailing list that architecture is not the set of decisions made early but the decisions you wish you could get right early — a distinction that shifted focus from planning to learning.
  • Christopher Alexander’s A Pattern Language (1977) originated the pattern-language approach to describing architectural decisions, an influence that runs through this book and through the Gang of Four’s Design Patterns, which brought the concept to software.