Software Architect · Module 04

Even a strong team loses to a system that can't be held in one head.

Cognitive load · bounded context · Conway's Law

§ 01

Architecture exists to reduce unnecessary complexity, not to showcase the author's intellectual range.

Not all complexity is the same

A pilot needs to know the aerodynamics of the plane. They don't need to remember the serial number of every bolt in the passenger seat.

Intrinsic cognitive load is the complexity of the domain itself. A financial system has money, postings, limits, regulation. That can't just be removed. Extraneous cognitive load is the extra complexity created by the architecture: incidental dependencies, magic, non-obvious side effects, five ways to do the same thing.

The architect's job is to shield the team from extraneous load. Good architecture doesn't make the domain simple, but it makes it understandable.

Bounded context cuts the noise

At an airport, "gate" means the boarding gate. In logistics, "gate" can mean the warehouse gate. Same word, different worlds.

A bounded context is a boundary inside which the model and the language stay consistent. The customer in billing and the customer in support are often not the same object. Trying to build a universal "customer" model can increase cognitive load: every engineer has to remember every exception across every domain.

A good bounded context lets an engineer work locally: understand the language, the invariants, and the dependencies of just that area.

§ 02

If a change forces you to hold the whole system in your head, the boundaries are wrong.

Example: a team owns checkout

A restaurant shift owns the kitchen end to end: ingredients, process, plating, quality. It doesn't call head office for every order.

The checkout team owns cart, pricing snapshot, payment intent, order creation, and failure handling. It has clear APIs to catalog and identity. It doesn't reach into warehouse directly — it publishes an OrderPlaced event.

That cut reduces cognitive load: the team understands its flow end to end and doesn't carry the whole company in its head.

Anti-example: the shared-everything layer

A shared cupboard works fine until everyone starts dumping their tools in it without labels.

The shared folder often turns into a junk drawer: validators, formatters, domain models, API clients, permissions, constants. Any change becomes risky, because nobody knows who else depends on that code.

Shared code has to be either very stable or very small. Otherwise it amplifies coupling and cognitive load.

Self-check
  • Can the module be explained without referencing the neighbouring modules? - Where in the system does too much rely on implicit knowledge? - Which shared pieces change too often? - Do team boundaries and architecture boundaries line up?