왜 하필 헥사고날인가?

반응형
반응형

DDD로 개발하라고 그러면 보통 헥사고날로 개발하지 않으면 DDD가 아니라고 말을한다.
사실 이건 틀린 주장이라 생각한다. 애초에 DDD는 도메인 주도 개발으로 도메인을 중심으로 개발하면 상관없다.

domain1
  controller
  service
  repository
domain2
  controller
  service
  repository
domain3
  controller
  service
  repository

이렇게 개발해도 도메인이 중심이기 때문에 이렇게 해도 DDD라고 말할 수 있다.
하지만 저 구조에는 아주 치명적인 문제가 존재한다.
바로 어떻게 데이터를 보내는지 즉, 통신에 문제가 발생한다. 왜냐하면 도메인1에서 데이터를 도메인2에게 데이터를 보내는 경우 혼재될 가능성이 존재하기 때문이다. 이걸 해결하기 위해 몇 가지 아키텍처가 존재한다. 첫번째는 레이어드 아키텍처이고 두번째가 헥사고날 아키텍처다. 지금 이 글은 헥사고날이 주제이기때문에 아주아주 짧게 설명하면 두 아키텍처는 아주 큰 차이가 존재한다. 레이어드는 계층의 통신에 중점을 둔 아키텍처이고 헥사고날은 데이터의 흐름에 대해 중점을 두는 아키텍처다.

일반적으로 확인했을때 요러한 그림들을 확인 할 수 있다.

https://reflectoring.io/spring-hexagonal/

내가 생각할때 그림은 아무래도 상관없다고 생각한다. 

헥사고날의 기본구조는 다음과 같다.
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

댓글

Designed by JB FACTORY