클린 아키텍처는 비즈니스 로직을 외부 의존으로부터 격리하고, 의존 관계를 한 방향으로 제한하는 설계 기법입니다.
"외부 세계(DB, 웹 프레임워크, API)는 변하기 쉽다"
"이 내부 세계(비즈니스 규칙)는 변하기 어렵다"
라면, 내부(비즈니스 규칙)를 외부(인프라)로부터 보호하는 것이 자연스러울 것입니다.
┌─────────────────────────────────────┐
│ Framework/Driver층 — Web, DB, API │ ← 외부 세계(변하기 쉬움)
└──────────────┬──────────────────────┘
...
규칙: 내부의 계층은 외부의 계층을 알지 못한다. 의존은 외부 → 내부 방향만 가능하다.
src/
domain/ # 엔티티・포트 (외부 의존 없음)
usecases/ # 유스케이스 (도메인에만 의존)
...
"도메인이 원하는 것"을 정의합니다.
# domain/ports.py
from typing import Protocol
class ReservationRepository(Protocol):
...
외부 시스템(SQLite, SendGrid 등)이 Port를 구현합니다.
# adapters/sqlite_repository.py
import sqlite3
from domain.entities import Reservation
...
# domain/entities.py
from dataclasses import dataclass
@dataclass
...
# usecases/create_reservation.py
class CreateReservationUseCase:
def __init__(
...
| 장점 | 설명 |
|---|
| 테스트하기 쉬움 | Domain・UseCase층은 외부 의존이 없으므로 단위 테스트가 간단함 |
| 변경에 강함 | DB를 SQLite → PostgreSQL로 바꿔도, Domain층은 변경 불필요 |
| 재사용하기 쉬움 | Web API든 CLI든 같은 UseCase를 사용할 수 |
클린 아키텍처의 핵심은 **"내부를 외부로부터 보호하는 것"**입니다.
| 포인트 | 내용 |
|---|
| 4개 계층 | Domain → UseCase → Adapter → Framework |
| 의존 방향 | 외부 → 내부만 (내부에서 외부로의 의존은 금지) |
| Port/Adapter | 외부 의존은 인터페이스로 추상화 |
작은 앱에서는 과도한 설계일 수 있지만, 업무 로직이 복잡해진 단계에서 도입해 보는 것을 추천합니다.
본 기사는 개인 Zenn에서도 공개하고 있습니다.