지금까지 아키텍처를 고민할 때 exact 정확한 헥사고날 아키텍처 뿐 아니라, 여러가지 ‘클린 아키텍처’ ‘레이어 분리’등 패러다임들이 유기적으로 엮어 적절한 아키텍처를 구사했던 것 같다. 하지만 이번 강의 + 정리를 통해 헥사고날 아키텍처의 본질은 통합 방식의 유연성과 방향성에 있다는 것을 다시 한 번 깨달았다. DDD 뿐 아니라, 패러다임을 알아가면서 느끼는 점은 이들은 방향성을 도울 뿐, 정해진 답이 없다는 얘기한다. 상황에 따라 최적의 솔루션을 찾아가는 여행, 그리고 그 여행의 방향키는 우리에게 주어진다는 점이 매력적인 것 같다. ⛵️…
UseCase
가 많이 사용되지만, 반드시 UseCase
라는 접미사를 붙일 필요는 없다.LoadUserPort
, SaveOrderPort
, UpdateInventory
등For~ing
스타일의 권장 네이밍도 있기는 하다, 행위 지향적 표현을 유도하는 장점이 있다. (어색)
ForCreatingProduct
, ForSendingEmail
@Entity
, @Repository
) 및 설정등이 core 영역에 노출되면 되는지?이부분은 가장 많은 고민을 했고, 아직도 고민을 하게 되는 부분이다. 🤔 …
- 하지만 여기서 중요한건 애플리케이션 코드와 포트 인터페이스가 외부 기술에 종속되지 않도록 해야 한다.
- 즉, 포트 인터페이스에는 기술 의존적인 이름을 가지면 안된다
- ex)
jpa어쩌고 저쩌고
,redis어쩌고 저쩌고
등- 확신의 ex) ❌
JpaUserRepositoryPort
- 대신 이런식으로 목적이 드러나도록 사용 ✅
LoadUserPort
- 또한 애플리케이션은 모든 외부와의 상호작용을 위해서 provided interface, required interface를 정의해야 한다.
- JPA Repository는 사실상 인터페이스이고, 실 구현체는 Spring이 DI로 구현체를 주입하므로 포트로써 사용할 수 있다.
- 즉, 포트 인터페이스로 선언한 후, 그 구현체가 Spring Data JPA Repository여도 무방하다.
- 다만 기술 의존성이 드러나지 않도록 네이밍과 위치에 주의해야 한다.
- 즉, “Repository는 무조건 어댑터에 있어야 한다”는 건 과도한 제약일 수 있다.
- 이 부분은 실무에서 명확한 팀 컨벤션이 필요하며, 이견이 많아질 수 있는 포인트다.
도메인 모델에는 JPA 엔티티 관련 설정이 없는 pojo에 가깝도록 설계하는 식으로 가고, 매퍼에서 이를 매핑하는 방식으로 …
- ex) MapStruct, Converter 클래스 등 사용하여 매핑
- 이부분은 조금 더 강의를 들어보고 얘기도 나눠보고 내용을 보충해야 겠다.
provided
와 required
인터페이스를 정의한다.JpaUserRepositoryPort
의외로 자주 볼 수 있는 네이밍LoadUserPort
@Controller
나 @KafkaListener
는 core 애플리케이션 영역으로 들어가면 안 됨포트(Port) : 애플리케이션 입·출력 인터페이스, 핵심 영역을 보호 |
어댑터(Adapter) : 외부 세계와의 연결자 (Web, DB, 메시지큐 등) |
방향성 : 어댑터가 포트를 구현한다. (의존성은 안쪽으로만!!!) |
비교 항목 | 클린 아키텍처 | 헥사고날 아키텍처 |
---|---|---|
중심 개념 | 계층 (Layered) 중심 | 경계 (Boundary) 중심 |
도메인 계층 | 명확히 존재 | 명확x 게층보다는 의존성 방향 |
기술 의존 분리 | 철저히 분리 | 선택적 분리 가능 |
헥사고날 아키텍처의 주장은 코드를 계층화하는 것이 아니라, 애플리케이션이 외부 세계와 소통하는 경로(포트)를 분리하고 명시하는 것임을 알게 되었다.
특히 Repository나 Controller등이 반드시 특정 위치에 있어야 한다는 인식보다,
외부 기술 종속을 최소화하고 의존성 방향을 외부에서 안쪽으로 유지하는 것이 더 중요한 원칙이라는 걸 배웠다.
즉, 헥사고날 아키텍처는 계층을 엄격히 나누는 것이 아닌, 의존성과 흐름을 어떻게 제어할지에 더 초점이 있는 구조라는 점을 이해하게 되었다.
특히 다양한 입출력 수단이 존재할 때, 포트와 어댑터 패턴이라고 불리기도 하는 헥사고날이 매우 유연한 선택이라는 점을 느꼈다. 포트와 어댑터를 명확히 나누고, 런타임에 유연하게 액터를 구성한다면
다양한 액터를 하나의 애플리케이션에서 효과적으로, 유연하게 통합할 수 있다고 생각했다. 다만 그만큼 아키텍처 설계에 대한 명확한 이해와 팀 간 컨벤션 정립이 없으면 의미가 퇴색되어지면서 구조가 쉽게 무너질 수도 있다고 생각했다.