0

Separation of concerns — each layer or module handles one aspect

Beginner5 min read·eng-16-003
interviewsolid

Definition

Separation of concerns is the principle that different aspects of a program — data storage, business logic, presentation, HTTP handling, validation — should be handled by distinct, non-overlapping layers or modules. When concerns are separated, each layer can be understood, tested, and changed independently. Mixing concerns in a single place creates code that is difficult to reason about because a change to one aspect may inadvertently affect another.

In Practice

php
<?php
// MIXED concerns: controller handles HTTP, business logic, AND persistence
class UserController extends Controller
{
    public function store(Request $request): JsonResponse
    {
        $data = $request->validate([
            'email' => 'required|email|unique:users',
            'name'  => 'required|string|max:255',
        ]);

        // Business logic should not live in a controller
        if (User::where('email', $data['email'])->exists()) {
            throw new DuplicateEmailException();
        }

        $user = User::create($data);
        event(new UserRegistered($user));

        return response()->json($user, 201);
    }
}

// SEPARATED concerns: controller handles HTTP only
class UserController extends Controller
{
    public function __construct(private RegisterUserAction $register) {}

    public function store(RegisterUserRequest $request): JsonResponse
    {
        $user = ($this->register)($request->validated());
        return response()->json($user, 201);
    }
}

In Laravel projects, separation of concerns maps directly onto the layer structure: controllers handle HTTP negotiation, Form Requests handle validation, service classes or action classes handle business logic, repositories handle persistence, and events handle cross-cutting side effects. Each layer speaks to the next through a defined interface, not by reaching through it.

In Context

Separation of concerns is often asked in system design interviews or code review discussions. The interviewer wants to hear you identify which layer a piece of logic belongs in and why. A common prompt is: "Where does validation belong in a Laravel app?" The correct answer is Form Request classes, not controllers or models — because validation is an HTTP concern, not a domain concern.

The common misconception is conflating separation of concerns with DRY. They are orthogonal. Separating concerns means putting different types of logic in different places, even if that logic is not duplicated. DRY means not repeating the same logic in multiple places. You can violate DRY while perfectly separating concerns.

Related terms: layered architecture (the structural pattern implementing separation of concerns at scale), cohesion (the class-level metric), MVC (Model-View-Controller — the most widely recognized application of this principle in web frameworks), and SOLID (all five principles support separation of concerns in various ways).