SOLID & DESIGN PRINCIPLES / OBJECT DESIGN BRIEF

Separation of concerns

Separation of concerns (SoC) means dividing a program into distinct parts, each addressing one concern: presentation, business rules, data access, communication, logging.

BeginnerPhase 02 / Topic 7 of 8ResponsibilitiesCollaborationsExtensibility
01

Overview

Separation of concerns (SoC) means dividing a program into distinct parts, each addressing one concern: presentation, business rules, data access, communication, logging. Each part can be understood, changed, and tested with minimal knowledge of the others.

SoC is the parent of SRP (applied to classes) and of layered architectures (applied to systems). Typical LLD layers are controller or CLI (input/output), service (use cases), domain model (rules), and repository (persistence). Mixing them, for example SQL inside UI handlers, makes every change risky.

A hospital

Reception handles check-in, doctors diagnose, the pharmacy dispenses, and billing charges. Each department has its own expertise; changing the billing system does not change how doctors diagnose.

02

When to use it

  • Structuring any application or LLD solution.
  • A single method mixes parsing input, rules, persistence, and output.
  • Cross-cutting concerns (logging, auth, caching) are copied everywhere.
03

Where it shows up in interviews

Layered solutions

Recognize it when: interviewer wants clean code structure.

  • Design a library system
  • Design a movie ticket booking service
Cross-cutting concerns

Recognize it when: logging, auth, metrics in every method.

  • Design a logging framework
  • Design an API middleware pipeline
04

Where it is used in real software

MVC

Model-View-Controller separates data, presentation, and input handling in Rails, Spring MVC, and ASP.NET.

HTML, CSS, JavaScript

The web separates structure, style, and behavior.

Middleware and AOP

Express middleware and Spring AOP apply logging, auth, and transactions separately from business code.

05

Key terms

Concern
A distinct aspect of functionality.
Layer
Group of components handling one concern level.
Cross-cutting concern
Needed by many components (logging, security).
Aspect / middleware
Mechanisms to apply cross-cutting concerns once.
06

How it works, step by step

  1. 1
    List the concerns

    Input, validation, rules, persistence, notifications, logging.

  2. 2
    Assign each to a layer or component

    Controller, service, domain, repository.

  3. 3
    Define interfaces between them

    Services call repositories through interfaces.

  4. 4
    Move cross-cutting logic to decorators or middleware

    Apply once.

  5. 5
    Check dependencies flow one way

    UI -> service -> domain; infrastructure implements domain interfaces.

07

Layers in a booking service

POST /bookings

Step 1 / 5
LayerConcernKnows about
ControllerHTTP parsing, status codesService
ServiceUse case: book seat, charge, notifyDomain, repository and notifier interfaces
DomainRules: seat availability, holdsNothing external
RepositorySQL and mappingDomain types
MiddlewareAuth, logging, metricsRequest context

NOWLayer: Controller | Concern: HTTP parsing, status codes | Knows about: Service

Changing from REST to a CLI touches only the controller; changing databases touches only the repository.

08

Implementation

// Controller: HTTP onlyapp.post("/bookings", async (req, res) => {  try {    const booking = await bookingService.book(req.body.showId, req.body.seat, req.user.id);    res.status(201).json(booking);  } catch (e) {    res.status(e instanceof SeatUnavailable ? 409 : 500).json({ error: (e as Error).message });  }}); // Service: use case orchestrationclass BookingService {  constructor(private shows: ShowRepository, private notifier: Notifier) {}  async book(showId: string, seat: string, userId: string) {    const show = await this.shows.get(showId);    const booking = show.reserve(seat, userId);   // domain rule    await this.shows.save(show);                  // persistence    await this.notifier.bookingConfirmed(booking); // notification    return booking;  }}
09

Complexity and performance

Layers3-4 typical

Controller, service, domain, repository.

Cost per changeLocalized

One layer at a time.

10

Trade-offs

Structure vs ceremony

Layers add files and mapping; tiny scripts do not need them.

Anemic domain risk

Pushing all logic into services leaves domain objects as data bags; keep rules in the domain.

11

Variants and related techniques

Vertical slices

Separate by feature first, then by layer within each slice.

Hexagonal architecture

Core domain separated from adapters on all sides.

12

Common mistakes

  • Business rules in controllers.

    Fix: Controllers translate I/O; rules belong in the domain or service.

  • Repositories returning HTTP DTOs.

    Fix: Each layer uses its own types or domain types.

13

Interview questions

How does SoC differ from SRP?

SoC is the general idea of dividing a system by concern at any level (layers, modules, languages). SRP applies it specifically to classes: one reason to change.

How would you handle logging across many services?

As a cross-cutting concern using decorators, middleware, or AOP, with structured logging configured centrally, rather than hand-written log calls mixed into every business method.

14

Practice problems

ProblemDifficultyWhat it trains
Layer a monolithic 'handle request' functionEasySplit concerns.
Add auth and metrics as middlewareMediumCross-cutting concerns.