Last updated: Apr 29, 2026
Separation of Concerns
Separation of Concerns is a software design principle that states that different parts of your code should handle different responsibilities, and they shouldn’t know about each other’s internals. UI layer shouldn’t contain business logic. Business logic shouldn’t know how data is stored. Data access layer shouldn’t format strings for display.
Example
Here’s a TicTacToe class that mixes display logic, input handling, and game rules all in one method:
class TicTacToe {
private board: string[][] = Array.from({ length: 3 }, () =>
Array(3).fill(""),
);
play(): void {
while (true) {
console.log(this.board); // display mixed in
const row = parseInt(prompt("Row:") ?? "0"); // input handling mixed in
const col = parseInt(prompt("Col:") ?? "0");
this.board[row][col] = "X";
// win checking mixed in
if (
this.board[0][0] === this.board[1][1] &&
this.board[1][1] === this.board[2][2]
) {
console.log("Winner!");
break;
}
}
}
}
Separated into Board, Display, and InputHandler — each with its own responsibility:
class TicTacToe {
constructor(
private board: Board,
private display: Display,
private inputHandler: InputHandler,
) {}
play(): void {
while (!this.board.hasWinner()) {
this.display.render(this.board);
const move = this.inputHandler.getNextMove();
this.board.makeMove(move);
}
this.display.showWinner(this.board.getWinner());
}
}
Now if you want to switch from console to a GUI, you only touch InputHandler. New win conditions only go in Board. A display redesign only touches Display. Each change is isolated and each part can be tested on its own.
In System Design
Here’s how SoC can be applied to system design:
- Layered Architecture — presentation, business logic, and data access live in separate layers that communicate through defined interfaces
- MVC — Model, View, and Controller are three isolated concerns within a single application
- Component-Based Design — the system is a collection of self-contained, reusable components each addressing one concern
- Microservices — each service owns one business domain end-to-end, independently deployable and scalable
- Modularization and Composition — break down the system into smaller, more manageable modules or components, each addressing a specific concern
- Cross-cutting concerns — logging, auth, and error handling are extracted out of core logic, typically via middleware or aspect-oriented patterns