본문 바로가기

- others

[Architecture]헥사고날 아키텍처(port and adapter)

반응형

새로운 아키텍처를 도입하면서, 학습한 내용을 정리했습니다.

학습 시작 서적은 접근하기 쉬운 두께를 가졌으면서, 아키텍처에 대해서만 다루고 있는 '만들면서 배우는 클린 아키텍처' 서적으로 시작했습니다.

http://www.yes24.com/Product/Goods/105138479

 

계층형 아키텍처의 문제점

  • 계층형 아키텍처는 데이터베이스 주도 설계를 유도
  • 데이터베이스의 구조를 먼저 생각하고, 이를 토대로 도메인 로직을 구현, 이는 의존성 방향에 따라 자연스럽게 구현한 것이지만 비즈니스 관점에선 전혀 맞지 않는 방법

  • 데이터베이스 중심적인 아키텍처가 만들어지는 가장 큰 원인은 ORM 프레임워크를 사용하기 때문에 영속성 계층과 도메인 계층에 강한 결합
  • 지름길을 택하기 쉬워진다
    • 전통적인 계층형 아키텍처에서 전체적으로 적용되는 유일한 규칙은, 특정한 계층에서는 같은 계층에 있는 컴포넌트나 아래에 있는 계층에만 접근 가능
    • 만약 상위 계층에 위치한 컴포넌트에 접근해야 한다면 간단하게 컴포넌트를 계층 아래에 두어 잘못된 의존성 발생

  • 그 외에도 테스트가 어려워지고, 유스케이스를 파악하기 어려워지며 동시 작업이 어렵다는 단점이 존재

 

헥사고날 아키텍처(포트 앤 어댑터) 소개

  • 육각형 안에는 도메인 엔티티와 이와 상호작용하는 유스케이스가 존재
  • 외부로 향하는 의존성이 없기 때문에 클린 아키텍처에서 제시한 의존성 규칙이 그대로 적용
  • 대신 모든 의존성은 코어(도메인 엔티티)
  • 패키지 구조
    • 패키지는 domain, application, adapter로 분리
    • domain: 도메인 모델 포함
    • application: 서비스 계층, 유스케이스 구현
      • 계층간 의존성을 지키기 위해 외부 접근은 in, out 패키지 내에 public으로 선언된 interface로 제어
    • adapter: 외부 접근(Web Adapter, 계층형에서 Controller), 외부 출력(Persistence Adapter, 영속성 기능 사용-DB )
    • 클린 아키텍처에서 제시한 의존성을 지키기 위해 application 계층에서 adapter 계층으로 의존성을 가지지 않음

  • Persistence Adapter
    • 헥사고날 아키텍처에서 Persistence Adapter는 주도되는(아웃고잉) 어댑터
    • application 계층에 의해 호출되기만 하고 application 계층을 호출하지 않아 아웃고잉 어댑터라 명칭
    • 아래 이미지에서 port는 application과 adapter 사이의 간접적인 계층

 

경계 간 매핑

  • 정답이 정해져있지는 않지만, 해당 서적에서 소개한 가이드 라인은
    • 웹 계층과 애플리케이션 계층 사이에서는 완전 매핑
    • 애플리케이션 계층과 영속성 계층 사이에서는 매핑하지 않기
    • 애플리케이션 계층과 영속성 계층 사이에서 영속성 문제를 다뤄야 한다면 양방향 매핑
  • 책에서 서술되어 있지는 않지만, 애플리케이션 계층과 영속성 계층의 엔티티가 일치하더라도 프로젝트가 거대해질 수록 차이가 생길 가능성이 크기 때문에 양방향 매핑을 선택하는 것이 안정적

  • 도메인 계층에 인터페이스를 도입하여  의존성을 역전 시키고, 영속성 계층이 도메인 계층에 의존

 

아키텍처 경계 강제

  • 자바의 접근 제한자
    • package-private(default) 접근제한자를 사용하여 자바 패키지를 기준으로 클래스들을 모듈화
    • 모듈 내의 클래스 간 접근은 허용하지만, 모듈 외부에서 접근을 차단
    • 모듈의 진입점으로 활용될 클래스만 public으로 만들면 의존성 규칙을 위반할 위험이 감소
      • public으로 선언된 in, out 패키지 내의 클래스
    • 작은 프로젝트에서는 효율적이지만, 하나의 패키지가 방대해지면 비효율
      • 가독성을 위해 하위 패키지를 생성하게 되면 다른 패키지로 취급되어 접근이 불가능
      • 하위 패키지로 접근이 가능하도록 public 으로 생성하게 되면 아키텍처의 의존성 규칙이 불안정
  • 컴파일 후 체크
    • 컴파일 후 런타임 체크
      • ArchUnit 도구 활용
        • 의존성 방향이 기대한 대로 잘 설정돼 있는지 체크할 수 있는 API를 제공, 의존성 규칙 위반할 경우 테스트를 실패
    • 단점으로는, 코드와 함께 늘 유지보수의 대상이 되는 점
  • 빌드 아티팩트
    • 각 패키지를 멀티모듈로 나눠서 의존성을 벗어나는 경우 빌드 자체를 실패하도록 제한하는 방법
    • 장점
      • 모듈 간 순환 의존성 제거
      • 모듈 간 독립적으로 격리한 채 특정 모듈 수정 가능
      • 개발자가 다른 모듈의 클래스에 의존성을 추가하기 전 다시 한번 생각
    • 단점
      • 세부적인 모듈로 분리하는 방식으로 개발속도나 가독성이 저하
      • 안정화되지 않은 프로젝트에서는 적용이 쉽지 않음
    • 책에서는 궁극적으로 빌드 아티팩트를 적용해야 된다고 하지만, 신규 프로젝트가 아닌 기존 프로젝트에 모두 적용하기에는 어려움이 있다고 생각

 

헥사고날 아키텍처는 도메인 로직이 많을 때 유용할 것 같습니다.

그래서 책에서도 DDD와 잘 어울리는 아키텍처라고 표현합니다.

“외부의 영향을 받지 않고 도메인 코드를 자유롭게 발전시킬 수 있다는 것은 육각형 아키텍처 스타일이 내세우는 가장 중요한 가치다.“

 

반응형

'- others' 카테고리의 다른 글

[Jenkins] Git, Bitbucket 연동  (0) 2021.05.08
[Jenkins] 설치 - Linux  (0) 2021.05.08
Cloud Native Application 고려사항  (0) 2021.05.06
Gradle Multi Module 프로젝트 생성  (0) 2021.05.01
[탐색알고리즘] DFS  (0) 2020.11.21