본문 바로가기
★ 프로젝트 + 트러블 슈팅 ★

헥사고날 아키텍처 구조, 사용이유 및 부가정보

by 리승우 2024. 11. 20.

이번에 진행 중인 DDD+헥사고날 프로젝트를 하며 아래 서적을 읽었다.

- 만들면서 배우는 헥사고날 아키텍처 설계와 구현

 

책에 정의된 헥사고날 아키텍처의 구조 및 사용이유에 대해 정리해두면 추후 요긴하게 사용할 것 같아, 해당 문서에 기술해둔다.

 

헥사고날 아키텍처

  • 비즈니스 코드를 기술 코드로부터 분리
  • 기술 측면이 비즈니스 측면에 의존하는지도 확인하여, 비즈니스 측면이 비즈니스 목표를 달성하는 데 사용되는 기술에 대한 우려 없이도 발전할 수 있게 함
  • 관련된 비즈니스 코드에 피해를 주지않고도 기술 코드를 변경할 수 있게 함

⇒ 이를 위해 도메인 헥사곤을 생성 (엔티티 + 값 객체)

⇒ 엔티티 >> 식별자를 할당할 수 있는 것을 의미

⇒ 값 객체 >> 엔티티들을 합성하기 위해 사용하는 불변 컴포넌트

 

 

도메인 헥사곤

  • 실 세계 문제를 이해하고 모델링하는 활동을 나타냄
  • 중요한 비즈니스 데이터와 규칙에 관련된 엔티티 및 값 객체들이 있음 (이것들은 실제 문제에 대한 모델을 나타내기 때문에 중요함)

엔티티

  • 연속성과 정체성을 가지는 객체
  • 연속성 객체의 수명주기 및 변경 가능한 특성이 관련있음. (시간이 지나면서 속성이 변할 수 있다는 의미이며, 수명주기를 가진다는 뜻)
  • 정체성 엔티티는 고유해야하므로 식별자를 가져야함. 이게 정체성에 대한 의미

값 객체

  • 무언가 고유하게 식별할 필요가 없는 경우는 물론이고, 정체성보다는 속성에 관심을 갖는 객체
  • 도메인 전체에서 예상치 못한 불일치를 방지하기 위해 값 객체는 변경할 수 없게 해야함

 

 

애플리케이션 헥사곤

  • 애플리케이션 특화 작업을 추상적으로 처리하는 곳
  • 아직 기술 관심사를 직접 다루지 않기 때문에 추상적인 것을 이야기함
  • 도메인 비즈니스 규칙에 기반한 소프트웨어 사용자의 의도와 기능을 표현함
  • 구성요소
    • 유스케이스
      • 유스케이스는 엔티티 및 다른 유스케이스와 직접 상호작용하고 그것들을 유연한 컴포넌트로 만듦
      • 자바에서 유스케이스는 소프트웨어가 할 수 있는 것을 표현하는 인터페이스로 정의된 추상화로 보여줌
    • 입력포트
      • 유스케이스가 소프트웨어가 하는 일을 설명하는 인터페이스라면, 해당 인터페이스를 구현하는 곳
    • 출력포트
      • 유스케이스가 목표를 달성하기 위해 외부 리소스에서 데이터를 가져와야하는 상황이 있을 것임. 그리고 이때 사용하는 것이 출력 포트의 역할임.
  • input
    • 수동적으로 요청받는 것
  • output
    • 능동적으로 요청하는 것

 

 

프레임워크 헥사곤

  • 소프트웨어와 통신할 수 있는 기술을 결정하는 곳
  • 통신은 아래 2가지 형태로 발생할 수 있음
    • 드라이빙 (입력 어뎁터 == Input Adapter)
    • 드리븐 (출력 어뎁터 == Output Adapter)
  • 드라이빙 오퍼레이션
    • 소트프웨어(애플리케이션)에 동작을 요청하는 것
  • 입력 어뎁터
    • 요청이 들어오는 곳 (API를 기준으로 보았을 때, 프로토콜을 정의할 수 있는 곳임)
    • 사용자의 요청을 받아들일 때 사용되는 Adapter
  • 드리븐 오퍼레이션
    • 애플리케이션에서 트리거되고, 외부에서 소트프웨어 요구사항을 충족시키는 데 필요한 데이터를 가져오는 것
  • 출력 어뎁터
    • 데이터를 어떻게 가져올지에 대해 정의하는 곳
    • 도메인 모델의 처리에 사용되는 Adapter



위 구조 및 내용들을 정리하면, 헥사고날 아키텍처의 핵심을 아래와 같이 한 마디로 정리할 수 있을 것 같다.

외부와의 통신을 인터페이스로 추상화하여 비즈니스 로직 안에 외부 코드나 로직의 주입을 막는다.

 

 

왜 헥사고날을 쓰는가?

  • 변경 허용
    • 포트와 어뎁터라는 특성을 이용하여 마찰이 적고 기술 변화를 흡수할 준비를 해두었기 때문에, 기술 변화가 빠르게 일어나는 현재 시점상 변경에 강함
  • 유지보수성
    • 비즈니스 규칙을 변경해야 하는 경우, 유일하게 변경해야하는 곳은 도메인 헥사곤임.
    • 아직 애플리케이션에서 지원하지 않는 특정 기술이나 프로토콜을 사용하는 기존 기능을 고객이 트리거할 수 있게 허용해야 하는 경우 프레임워크 헥사곤에서 실행할 수 있는 새로운 어뎁터를 만들면 됨
    ⇒ 관심사 분리를 통해서 복잡성을 단순하게 볼 수 있게 구조화함

  • 테스트 용이성
    • 외부 의존성이 없더라도 개발자가 애플리케이션을 테스트 할 수 있는 구조임


DIP (의존성 역전 원칙)

  • 상위수준 컴포넌트는 하위수준 컴포넌트에 의존해서는 안 된다. 대신 이들 모두는 추상화에 의존해야 한다.
    • 상위수준 컴포넌트
      • 주요 시스템 동작을 제공하기 위해 조정된 일련의 오퍼레이션을 가짐
      • 구체적이거나 추상적인 요소일 수 있음
    • 하위수준 컴포넌트
      • 상위수준 컴포넌트의 목표를 지원하기 위해 특별한 동작을 사용할 수 있음
      • 항상 구현 세부사항을 제공해야하기 때문에 구체적이여야 함

댓글