intermediate 2 min answer

A team applies a strict layered architecture and finds every change touches nine files. Is layering wrong, or is the application wrong?

ramplayeringconcernsboilerplatejudgement
Show the full answer Hide the answer

What has gone wrong

Layering is being applied by convention rather than by responsibility. Nine files for a single-field change means the layers are not separating different concerns — they are restating one concern at four altitudes.

A layer earns its place when it has a distinct responsibility that genuinely differs from the layers around it. A "service layer" that forwards calls from a controller to a repository has no responsibility; it is a naming convention with a file.

The diagnostic

Count the files a small, well-understood change touches. One to three — the schema, an index if performance requires it, a policy if the field needs one — is healthy. Nine is a tax paid by every feature for the life of the system.

Check the opposite direction too. If a cross-cutting change — adding a tenant identifier to every audit record, a new authorisation dimension — is cheap while a single-field change is expensive, the separation is inverted: the structure is optimised for a kind of change that rarely happens.

What genuinely justifies a layer

  • A boundary that is deliberately different in shape, such as a public API contract that intentionally differs from the internal model so the release cadences are decoupled. The distinction is whether the two shapes differ on purpose or merely because a template said so.
  • A replaceable dependency behind a port, where replacement is plausible.
  • A place where a cross-cutting concern is applied once — authorisation, transaction management, validation — rather than repeated.

What to do about it

Delete the layers that only translate. A mapper copying fields one-to-one between identical shapes is not an abstraction boundary; it is a place to make mistakes.

And accept the cost where it is real: collapsing layers couples the persistence shape to the wire shape, so a database change becomes an API change. That is a fair trade in an internal service and a bad one in a public API — which is exactly the judgement that layering-by-convention avoids making.