왜 하필 헥사고날인가?
- 항해플러스WIL
- 2025. 5. 25. 21:53
DDD로 개발하라고 그러면 보통 헥사고날로 개발하지 않으면 DDD가 아니라고 말을한다.
사실 이건 틀린 주장이라 생각한다. 애초에 DDD는 도메인 주도 개발으로 도메인을 중심으로 개발하면 상관없다.
즉
domain1
controller
service
repository
domain2
controller
service
repository
domain3
controller
service
repository
이렇게 개발해도 도메인이 중심이기 때문에 이렇게 해도 DDD라고 말할 수 있다.
하지만 저 구조에는 아주 치명적인 문제가 존재한다.
바로 어떻게 데이터를 보내는지 즉, 통신에 문제가 발생한다. 왜냐하면 도메인1에서 데이터를 도메인2에게 데이터를 보내는 경우 혼재될 가능성이 존재하기 때문이다. 이걸 해결하기 위해 몇 가지 아키텍처가 존재한다. 첫번째는 레이어드 아키텍처이고 두번째가 헥사고날 아키텍처다. 지금 이 글은 헥사고날이 주제이기때문에 아주아주 짧게 설명하면 두 아키텍처는 아주 큰 차이가 존재한다. 레이어드는 계층의 통신에 중점을 둔 아키텍처이고 헥사고날은 데이터의 흐름에 대해 중점을 두는 아키텍처다.
일반적으로 확인했을때 요러한 그림들을 확인 할 수 있다.
내가 생각할때 그림은 아무래도 상관없다고 생각한다.
헥사고날의 기본구조는 다음과 같다.
adapter, application, doamin 이렇게 존재한다. 그림에서 확인해보면 adater -> application -> doamin으로 데이터의 흐름을 확인 할 수 있다.
그런데 in과 out이라는 용어를 확인할 수 있다.
in은 다른말로 inbounded고 out은 outbounded다. 즉, 데이터가 들어오면 in 나가면 out이다.
이걸 흐름을 다시 작성해보면
adepter(in) -> application(in) -> domain -> application(out) -> adepter(out) 요런 흐름이 될거구
이것을 그림으로 대입시켜서 확인해보면 대략적으로 비슷하다는게 보인다.
그림에 usecase라고 있는데 이건 그냥 인터페이스고 application(in)에 해당된다.
근데 좀 이상하다. controller, service, repository는 저 흐름에서 어디에 넣어야 할까?
controller은 adepter(in)
service는 application
repository는 adepter(out)
으로 생각할 수 있다. 더 나아가 생각할 주제는 있겠지만 이제 본론으로 생각해보면
내가 생각할때 헥사고날 아키텍처로 개발하게 되면 소프트웨어의 흐름을 정확하게 이해 할 수 있을거라 생각한다.
어떤식으로 작성할지 어떤식으로 그릴지 개발하면서 가장 쉽게 접근 할 수 있는 아키텍처라 생각이 든다.
단순히 이게 DDD여서 이 아키텍처를 사용하는건 아니다. 그렇다면 유감이다.
나는 헥사고날을 사용하면 데이터의 흐름을 더 정확히 이해할 수 있지 않을까 생각한다.
여기까지 이해하면 일단 내가 알고 있는 내용은 전부 전달한거 같다.
이 파트에서는 헥사고날의 원칙이나 룰은 적지 않았다.
또한 아래는 in,out을 어떤식으로 표현할 수 있을지 gpt한테 물어봤다.
네이밍은 생각보다 중요하고 impl로 쓰는건 짜치다고 생각한다.
gpt 데이터 입니다.
역할 패키지 위치 예시 클래스명
📥 입력 어댑터 | adapter.in.web | PointController, WebhookReceiver |
📤 출력 어댑터 | adapter.out.jpa | JpaPointRepository, RedisPointStore |
유스케이스 실행 포트 | application.port.in | ChargePointUseCase, ReserveLectureUseCase |
외부 요청 포트 | application.port.out | PointRepository, SmsGateway |
유스케이스 구현 | application.service | ChargePointService, SyncUserPointService |
도메인 모델 | domain.model | Point, Lecture, User |
도메인 서비스 | domain.service | PointPolicy, CapacityValidator |
인터페이스 기준표
Port | 일반적인 용어 (IN/OUT 공통) | 헥사고날 문맥에서 가장 중립적인 표현 | PointRepository, PaymentPort |
Gateway | 외부 시스템으로 나가는 출입구 느낌 | 외부 API 통신 (결제, 인증 등) | KakaoPayGateway, AuthGateway |
Client | API Client 역할 강조 | Feign, WebClient 등 호출할 때 | UserInfoClient, ExternalApiClient |
SPI | Core에서 호출하는 구현 인터페이스 | Java 생태계에서 전통적인 명명 | NotificationSenderSPI |
예시 구조
com.moimserver
├── adapter
│ ├── in
│ │ └── web
│ │ ├── controller
│ │ └── dto
│ └── out
│ ├── jpa
│ ├── redis
│ └── kafka
├── application
│ ├── port
│ │ ├── in
│ │ └── out
│ ├── service
│ └── dto
├── domain
│ ├── model
│ │ ├── point
│ │ └── lecture
│ └── service
├── config
└── support (optional: 공통 예외, 유틸, 인터셉터 등)
'항해플러스WIL' 카테고리의 다른 글
[WIL] 1주차 TTD (0) | 2025.05.24 |
---|