71 lines
5.4 KiB
Markdown
71 lines
5.4 KiB
Markdown
---
|
|
category: Dev
|
|
tags: [Architecture, Design Patterns, DDD, SOLID]
|
|
title: Hexagonal Architecture (Ports and Adapters)
|
|
description: 도메인 로직을 외부 인프라스트럭처로부터 격리하여 시스템의 유연성과 테스트 용이성을 극대화하는 아키텍처 설계 패턴
|
|
last_updated: 2026-05-02
|
|
---
|
|
|
|
# Hexagonal Architecture
|
|
|
|
## 📌 Brief Summary
|
|
헥사고날 아키텍처(Hexagonal Architecture), 또는 **포트와 어댑터(Ports and Adapters)** 패턴은 소프트웨어의 핵심인 비즈니스 로직(도메인)을 데이터베이스, UI, 프레임워크와 같은 외부 요소로부터 완전히 격리하는 설계 방식입니다. 시스템을 내부(Inside/Domain)와 외부(Outside/Infrastructure)로 명확히 분리하며, 모든 상호작용은 정의된 인터페이스인 **포트(Port)**와 이를 구현하는 **어댑터(Adapter)**를 통해서만 이루어집니다. 이를 통해 기술 스택의 변경이 비즈니스 로직에 미치는 영향을 최소화하고, 독립적인 테스트가 가능한 견고한 시스템을 구축합니다.
|
|
|
|
---
|
|
|
|
## 📖 Core Content
|
|
|
|
### 1. 핵심 원리: 의존성 역전 (DIP)
|
|
전통적인 계층형 아키텍처(Layered Architecture)는 상위 계층이 하위 계층(특히 DB나 외부 라이브러리)에 직접 의존하여 기술적 변경에 취약했습니다. 헥사고날 아키텍처는 **의존성 역전 원칙(Dependency Inversion Principle)**을 극한으로 활용하여, 도메인과 인프라 모두가 추상화된 인터페이스(포트)에 의존하게 만듭니다.
|
|
|
|
### 2. 주요 구성 요소
|
|
* **도메인 (Inside):** 애플리케이션의 핵심 비즈니스 로직과 규칙을 포함하는 순수 코드 영역입니다. 외부 프레임워크나 데이터베이스 기술에 대한 지식이 전혀 없는 상태로 유지됩니다.
|
|
* **포트 (Ports):** 내부와 외부를 연결하는 명세(Interface)입니다.
|
|
* **입력 포트 (Inbound/Driving Ports):** 외부(UI, API 호출 등)에서 도메인 기능을 호출할 때 사용하는 인터페이스입니다.
|
|
* **출력 포트 (Outbound/Driven Ports):** 도메인이 외부 자원(DB, 메시지 큐, 외부 API)에 접근해야 할 때 사용하는 인터페이스입니다.
|
|
* **어댑터 (Outside):** 포트를 구체적으로 구현하거나 호출하는 인프라 계층입니다.
|
|
* **입력 어댑터:** REST Controller, CLI, WebSockets 등 외부 요청을 도메인이 이해할 수 있는 형식으로 변환하여 입력 포트를 호출합니다.
|
|
* **출력 어댑터:** 도메인의 요청을 받아 실제 DB(JPA, MongoDB), 외부 메일 서버, 알림 서비스 등으로 전달하는 구체적인 기술 구현체입니다.
|
|
|
|
### 3. 실전 설계 전략 (Framework Specific)
|
|
* **Spring Boot (Java):** 도메인 모델을 `@Entity` 등 프레임워크 어노테이션에서 분리하여 POJO로 구성합니다. `@Configuration`을 사용하여 어댑터 구현체를 런타임에 도메인 서비스에 주입합니다.
|
|
* **NestJS (TypeScript):** 모듈 시스템과 DI를 활용합니다. `Domain`, `Application`, `Infrastructure`, `Presentation` 계층을 폴더 구조로 명확히 나누고, 인터페이스 기반 프로그래밍을 강제합니다.
|
|
|
|
---
|
|
|
|
## ⚖️ Trade-offs & Caveats
|
|
|
|
### ✅ Benefits
|
|
* **높은 테스트 용이성:** 외부 DB나 API 없이도 모킹(Mocking)을 통해 도메인 로직만 완벽하게 테스트할 수 있습니다.
|
|
* **기술 독립성:** 데이터베이스나 메시징 시스템을 교체할 때 도메인 코드를 수정할 필요가 없습니다.
|
|
* **유지보수성:** 비즈니스 규칙이 한곳에 집중되어 있어 코드 파악과 변경이 용이합니다.
|
|
|
|
### ⚠️ Challenges
|
|
* **초기 복잡성:** 단순한 CRUD 앱의 경우, 수많은 인터페이스와 매핑 객체(DTO/Mapper)가 오버헤드로 작용할 수 있습니다.
|
|
* **보일러플레이트:** 계층 간 데이터 변환을 위한 코드가 늘어납니다.
|
|
* **학습 곡선:** 전통적인 계층 구조에 익숙한 팀에게는 패러다임 전환을 위한 비용이 발생합니다.
|
|
|
|
---
|
|
|
|
## 🔗 Knowledge Connections
|
|
|
|
### Related Concepts
|
|
* [[Dependency_Inversion_Principle]]: 헥사고날 아키텍처의 기술적 토대가 되는 원칙입니다.
|
|
* [[Clean_Architecture]]: 비즈니스 로직을 중심에 두는 유사한 철학의 아키텍처 패턴입니다.
|
|
* [[Domain_Driven_Design]]: 헥사고날 아키텍처 내부(도메인)를 채우는 모델링 방법론을 제공합니다.
|
|
* [[Dependency_Injection]]: 포트와 어댑터를 런타임에 결합하는 실무 도구입니다.
|
|
|
|
### Practical Application Contexts
|
|
* **System Design:** UI나 DB를 먼저 설계하지 않고, 비즈니스 유스케이스와 포트를 먼저 정의하는 '도메인 중심' 접근을 권장합니다.
|
|
* **Maintenance:** 레거시 시스템을 점진적으로 개선할 때, 외부 통신부를 어댑터로 격리하여 안전하게 로직을 추출할 수 있습니다.
|
|
|
|
---
|
|
|
|
## 💡 Adjacent Topics
|
|
* [[Test_Driven_Development]]: 헥사고날의 격리성을 활용하여 테스트 중심 개발을 가속화합니다.
|
|
* [[CQRS]]: 대규모 시스템에서 명령(Write)과 조회(Read) 포트를 분리하여 성능을 극대화하는 전략과 궁합이 좋습니다.
|
|
* [[Microservices]]: 각 마이크로서비스 내부 아키텍처로 헥사고날을 적용하여 서비스 간 독립성을 확보합니다.
|
|
|
|
---
|
|
*Last updated: 2026-05-02*
|