Arch | 클린 아키텍처

Lumpen·2025년 10월 1일

아키텍처

목록 보기
3/4

클린 아키텍처 한눈에 보기


1) 요약

  • 목적: 기술 독립성, 테스트 용이성, 유지보수성 극대화
  • 원리: 의존성 역전 원칙(DIP). 코어(엔티티·유스케이스)는 추상(포트)에 의존하고, 외부는 어댑터로 구현
  • 관계: 헥사고날(Ports & Adapters) 사상을 동심원 구조로 일반화. UI는 MVP/MVVM 등으로 구성
  • 효과: 데이터베이스·프레임워크·UI 교체 시 코어 변경 최소화

2) 구조

[Frameworks & Drivers]
  └─ DB, Web, UI, Devices, External Services
         ▲          
         │ Adapters (구현)
         │
[Interface Adapters]
  └─ Presenter / Controllers / Gateways / Repository Impl
         ▲
         │ (Ports: Interfaces)
[Use Cases]
  └─ Application Business Rules
         ▲
[Entities]
  └─ Enterprise Business Rules

핵심: 모든 의존 화살표는 안쪽(엔티티·유스케이스)으로 향함. 안쪽은 바깥을 모릅니다.


3) 배경과 발전 흐름

  • DIP: 고수준·저수준 모두 추상에 의존해야 함 → 의존 방향을 코어 쪽으로 역전
  • 헥사고날(2005): 포트와 어댑터로 코어와 외부를 분리
  • UI 패턴(MVP/MVVM): 표시와 로직 분리는 헥사고날에서도 UI를 Primary Adapter로 배치해 달성 가능. 클린은 이를 Interface Adapters 층에서 MVP/MVVM 등으로 더 명시적·체계적으로 활용한다고 서술
  • 통합: 클린 아키텍처는 위 개념들을 동심원으로 통합해 기술 독립성을 체계화

3.1 헥사고날 ⇒ 클린

  • 모델링 관점: 헥사고날은 코어와 외부를 이분법적으로 가르되, 포트를 입·출력으로 구분합니다. 클린은 이를 동심원으로 표현해 “모든 의존 화살표는 안쪽으로”라는 단일 규칙으로 일반화합니다.
  • 계층 역할 명시: 클린은 Interface Adapters 층을 별도 계층으로 두어 Presenter·Controller·Gateway·Repository 구현의 역할을 분리해 서술합니다. 헥사고날에서 어댑터가 맡던 폭넓은 역할을 세분화해 팀 커뮤니케이션을 돕습니다.
  • 모델 분리 엄격화: 엔티티·유스케이스 모델과 DTO·프레임워크 모델을 분리하도록 강하게 권고합니다. 이로써 데이터 누수와 프레임워크 결합을 줄입니다.

3.2 UI 관리(헥사고날 vs 클린)

  • 헥사고날: UI는 Primary Adapter로서 Inbound Port를 구현해 코어를 호출합니다. 패턴 선택은 자유도가 높습니다.
  • 클린: UI는 Interface Adapters 층에 배치되며, MVP·MVVM 등 패턴을 명시적으로 활용해 View와 Presenter/ViewModel, 변환 계층을 도식화합니다. 테스트 경계와 모델 변환 지점이 명확해집니다.

10.6 헥사고날 ↔ 클린 비교

항목헥사고날클린
핵심 개념Ports(계약)와 Adapters(구현)동심원과 의존성 규칙(안쪽을 향함)
UI 위치Primary AdapterInterface Adapters 층 내부(프레젠터/뷰모델 활용)
포트 구분Inbound/Outbound 포트를 명확히 구분포트 개념은 유지하되 계층 역할 서술이 더 일반화
모델 전략코어와 어댑터 모델 분리 권장(표현은 비교적 느슨)엔티티·유스케이스 모델 vs DTO·프레임워크 모델 강한 분리
팀 온보딩간결하고 직관적이지만 해석 여지 큼역할 명세가 자세해 대규모 팀에 유리

4) 핵심 원칙

  • 의존성 규칙: 내부는 외부를 모르고, 외부가 내부에 맞춥니다
  • 경계 계약: Port(인터페이스)로 계약을 정의하고 Adapter가 구현
  • 모델 분리: 엔티티·유스케이스 모델과 전송/프레임워크 모델을 분리
  • 테스트 우선: 코어는 순수 로직으로 테스트가 빠르고 안정적

5) 레이어드 아키텍처와 비교

  • 공통점: 관심사 분리, 계층적 구조로 변경 영향 축소
  • 차이점: 레이어드는 구현 계층 간 의존이 수직 고정되기 쉬움. 클린은 포트·어댑터로 의존 방향을 항상 코어 쪽으로 강제하여 기술 독립성 강화
  • 실무 포인트: 기존 레이어드 위에 포트/어댑터를 덧대 코어 의존 역전을 달성하는 하이브리드가 현실적

6) 장단점

장점

  • 기술 교체 용이: DB, 메시징, UI, 프레임워크 교체 시 코어 변경 최소
  • 테스트 용이: 어댑터 대체로 코어 단위 테스트가 빠르고 견고
  • 유지보수성: 경계가 명확해 변경 범위가 좁음

단점

  • 초기 비용: 포트/어댑터, 경계 모델, 매핑 코드 필요
  • 과설계 리스크: 작은 서비스에 과도하면 생산성 저하
  • 팀 합의 필요: 경계, 계약, 패키징 규칙을 지속적으로 지켜야 함

7) 적용 체크리스트

  • 포트: 유스케이스가 필요로 하는 외부 기능을 인터페이스로 정의했는가
  • 어댑터: UI·DB·API 구현은 포트를 통해서만 코어에 접근하는가
  • 모델: 엔티티·유스케이스 모델과 DTO를 분리하고 매핑을 일관화했는가
  • 의존 화살표: import 방향이 항상 코어를 향하도록 패키징했는가
  • 테스트: 코어는 순수 단위 테스트, 어댑터는 계약 테스트를 갖추었는가

9) 안티패턴과 회피법

  • 리포지토리 누수: 어댑터 상세 타입이 코어로 새어 들어오지 않게 Port를 도메인 모델 기준으로 정의
  • 거대 유스케이스: 유스케이스가 오케스트레이션·검증·권한·트랜잭션까지 모두 품지 않도록 분리
  • 양방향 의존: 유스케이스가 어댑터 구현을 import하면 규칙 위반. 의존성은 항상 안쪽으로만
  • 경계 무시 매핑: DTO ↔ 도메인 매핑 로직을 일관된 위치에서 수행하여 중복·누락 방지

10) 헥사고날 아키텍처 (Ports & Adapters)

10.1 개요

  • 목적: 애플리케이션 코어와 외부 세계를 ‘포트(계약)’와 ‘어댑터(구현)’로 분리
  • 효과: 코어는 외부 세부사항을 모른 채로 기능을 유지. 구현 교체가 쉬움

10.2 구조 도식

      [Primary Adapters]         [Secondary Adapters]
(UI, CLI, HTTP Inbound)         (DB, HTTP Outbound, MQ)
           │                              ▲
           ▼                              │
        Inbound Port  ───►  Application  ├──► Outbound Port ───► Adapter(외부)
                 (인터페이스)           (UseCases)           (구현)
  • Inbound Port: 외부가 코어 기능을 호출하는 계약(Controller, Handler가 구현 가능)
  • Outbound Port: 코어가 외부 기능을 필요로 할 때 호출하는 계약(Repository 인터페이스 등)

10.3 클린 아키텍처와의 차이·관계

  • 차이: 헥사고날은 입·출력 방향을 분리해 포트를 두 축으로 명시. 클린은 동심원과 의존 규칙으로 일반화
  • 관계: 클린의 Interface Adapters 층이 헥사고날의 어댑터 군과 개념상 대응

10.5 장단점 요약

  • 장점: 입출력 포트를 분리해 의사소통 경계를 명확히 하고 테스트 대체가 용이
  • 단점: 포트 수가 증가해 인터페이스 관리 비용이 커질 수 있음

profile
떠돌이 생활을 하는. 실업자, 부랑 생활을 하는

0개의 댓글