Layered Architecture & Separation of Concerns
The problem
Mixing business logic, data access, and presentation code together in the same place makes each one hard to change without risking the others, and impossible to test in isolation — layering organizes a system into distinct responsibilities so each can change, and be tested, independently.
Why now
Coupling and cohesion established the general goal; layered architecture is one of the most common concrete structures for achieving it — grouping code by responsibility (what talks to the database, what holds business rules, what handles requests) into layers that only depend on the layer directly below them.
Mental model
A layered architecture is coupling and cohesion applied at the whole-application scale: each layer has one clear responsibility (cohesion) and depends only on the layer beneath it through a narrow interface, never reaching sideways or upward (low coupling) — which is exactly why a well-layered system lets you swap out a database or a UI framework without rewriting the business logic in between.
Requires
- Coupling & CohesionSoftware Architecture
A layer is, by definition, a cohesive grouping of one responsibility with controlled coupling to adjacent layers only; you need those two concepts already understood before evaluating whether a given layering is actually well-designed.
Unlocks
Used in
- The common presentation/business-logic/data-access layering in countless backend frameworks
- Testing business logic in isolation by substituting a fake data layer underneath it
- Explaining why changing a database (Postgres to MongoDB) shouldn't require rewriting business rules
- Identifying when logic has leaked into the wrong layer (e.g. business rules living inside a database query)
Projects
- Take a codebase with business logic and database queries mixed together in one function, and separate them into distinct layers with a clear interface between them
- Write a test for business logic that substitutes a fake/in-memory data layer, demonstrating the business logic can be tested without a real database
Examples
- A route handler that directly writes SQL mixes the presentation layer with data access; separating them lets the SQL be swapped or tested independently
- Business logic 'leaking' into a database trigger makes a rule invisible to anyone reading the application code, and untestable without a live database
Resources
Mastery checklist
- I can identify the layers in a layered architecture and each one's responsibility
- I can separate mixed-responsibility code into appropriate layers
- I can test business logic in isolation from the data layer
- I can identify logic that has leaked into the wrong layer