들어가며
보통 스프링 프로젝트를 시작하게 되면 계층형 아키텍쳐를 쉽게 채택한다.
계층형 아키텍쳐의 대안에 대해 미리 알아두고, 필요할 때 잘 채택할 수 있도록 해당 서적을 읽기 시작했다.
나아가 기존 프로젝트의 결합도를 낮출 수 있는 방법에 실습하며 익혀보고자 했다.
계층형 아키텍쳐
- 영속성 계층에 의존하기 때문에 데이터베이스 설계에 의존하게 된다.
- 데이터베이스의 구조를 먼저 생각하고, 이를 토대로 도메인 로직을 구현하게 된다.
- 영속성 개체에 대한 의존성이 높아지면, 개발자들의 병렬(동시) 작업에 어려움이 생길 수 있다.
- ex) 엔티티의 변경이 발생해 서비스 코드의 변화가 생김 -> merge conflict
의존성 역전
컴포넌트 사이의 의존성이 생기면 상위 컴포넌트의 변경이 생길 때 마다 하위 컴포턴트의 변경이 불가피하다.
앞서 언급한 계층형 아키텍쳐를 예를 들어 설명하자면, 영속성 객체를 변경하면, 도메인 계층 또한 변경이 생긴다.
사실 가장 근본적인 변화가 영속성 객체의 변경이라고 생각한다.
이런 수고를 덜어내기 위해 도메인, 영속성 레이어에 의존성 역전 법칙(IoC)을 적용하자.
도메인 레이어
- ORM이 관리하는 엔티티가 아닌, 도메인 레이어에서 사용하는 엔티티를 선언한다
- Repository 인터페이스를 선언한다.
영속성 레이어
- 도메인 레이어의 Repository 인터페이스를 구현한 RepositoryImpl을 생성하고
- ORM에서 관리하는 Entity를 위치시킨다.
위의 흐름대로 변경하게 되면 아래와 같은 구조를 가지게 된다.
이 과정을 통해 결국 도메인 레이어에서 관리하는 코드는 바깥으로 향하지 않게 된다.
클린 아키텍쳐
모든 의존성을 엔티티가 위치하는 중심을 향한다.
빨간색 계층에 해당하는 Use Cases가 서비스에 해당하는 계층이며 그림과 같이 세분화 된 것을 확인할 수 있다.
그러나 분야별로 엔티티 공유는 이루어지지 않기에 계층별로 엔티티를 만들어 주어야 하며, 계층 사이에 변환되는 경우를 대비하여 다양한 매핑 전략을 가지고 있다.
헥사고날 아키텍쳐
어플리케이션 코어에서 어댑터를 통해 상호작용하기 때문에 포트-어댑터 아키텍쳐라고도 불린다.
클린 아키텍쳐와 동일하게 모든 의존성은 코어를 향하며 의존성 규칙을 그대로 유지한다.
어댑터는 주도하는(Driving), 주도되는(Driven) 어댑터로 나눌 수 있다.
- 주도하는(Driving) 어댑터는 코어의 입력 포트를 통해 어플리케이션 코어를 호출한다.
- 입력 포트의 구현은 유스케이스가 담당
- 주도되는(Driven) 어댑터는 코어의 출력 포트를 통해 어플리케이션 코어에 의해 호출된다.
- 출력 포트의 구현은 어댑터가 구현한다.
클린 | 헥사고날 아키텍쳐의 장점 및 정리
두 아키텍쳐 모두 도메인 코드의 결합도를 낮춘다.
도메인 로직의 결합을 제거하고 영속성 문제로부터 비교적 자유로워지며, 코드 변경을 줄일 수 있다.
'Book > DEV' 카테고리의 다른 글
Effective Java - 상속과 합성 (0) | 2022.11.28 |
---|