계층형 아키텍처의 문제와 의존성 역전

계층형 아키텍처의 문제

  • 웹 계층, 도메인 계층, 영속성 계층으로 구성된 전통적인 계층형 아키텍처는 코드에 나쁜 습관이 스며들기 쉽게 만들고, 시간이 지날수록 변경이 어려워지도록 만든다.

  • ORM 프레임워크를 사용하게 되면서 서비스 로직이 Entity, Repository등에 의존하게 되어 데이터베이스 주도 설계를 유도한다.

  • 특정 계층은 같은 계층의 컴포넌트나 아래 계층만 접근가능하지만, 상위 컴포넌트에 접근하기 위해 아예 하위 컴포넌트를 상위 계층으로 올려버리는 만행을 쉽게 저지를 수 있다.

  • 기능을 추가하거나 변경할 적절한 위치를 찾는 일이 빈번한데, 계층형 아키텍처는 도메인 로직이 여러 계층에 흩어지기 쉽다.

  • 하나의 서비스에 비대한 양의 유스케이스가 존재하게 되어 영속성 계층에 많은 의존성을 갖게된다. 의존성이 많이 엮이면 서비스를 테스트하기도 어려워진다.

단일 책임 원칙

  • 컴포넌트를 변경하는 이유는 오직 하나뿐이어야 한다.

  • 널리 알려져있는 의미는 하나의 컴포넌트는 오로지 한 가지 일만 해야 하고, 올바르게 수행해야 한다 라는 것이지만, 결국 변경할 이유가 하나뿐이라면 자연스레 한 가지의 일만 하게 된다.

  • 변경할 이유는 컴포넌트 간의 의존성을 통해 쉽게 전파되므로, 컴포넌트 간의 의존성을 최소화하는 것이 중요하다!

의존성 역전

  • 코드상의 어떤 의존성이든 방향을 역전시킬 수 있다는 법칙이다.

  • 의존성의 양쪽 코드를 모두 제어 가능한 경우에만 의존성 역전이 가능하다.

  • 즉, 서드파티 라이브러리에 의존하는 경우 의존성 역전이 불가능하다.

도메인과 영속성의 의존성 역전 예제

  • 도메인 계층의 엔티티와 영속성 계층의 엔티티를 구분한다.

  • 도메인 계층에 리포지토리 인터페이스를 도입해 영속성 계층이 도메인 계층을 의존하도록 해 의존성을 역전시킨다.

  • 인터페이스를 작성할 때는 클라이언트가 필요로 하는 메서드를 기반으로 분리해야 한다.

  • 인터페이스의 이름, 메서드 이름을 정할 때도 구체적인 클래스의 이름을 드러내지 않는 것이 중요

클린 아키텍처

  • 클린 아키텍처에서 모든 의존성은 도메인 로직을 향해 안쪽 방향으로 향한다.

  • 계층 간의 모든 의존성은 안으로 향해야 한다.

  • 이로써 도메인 코드에서는 어떤 영속성 프레임워크나 UI 프레임워크를 사용하는지 알 수 없어 비즈니스 규칙에 집중하여 자유롭게 모델링할 수 있다.

헥사고날 아키텍처

  • 헥사고날 아키텍처는 어떤 프레임워크, 기술을 사용하는지에 의존하지 않고 도메인을 중심으로 개발할 수 있도록 해준다.

  • 도메인 엔티티에는 도메인의 정보들이 담긴다.

  • 유스케이스는 도메인 엔티티와 상호작용하며 비즈니스 로직을 수행한다.

포트와 어댑터

  • 좌측의 어댑터는 애플리케이션 코어를 호출해 애플리케이션을 주도하는 어댑터이다.

  • 우측의 어댑터들은 애플리케이션 코어에 의해 호출되어 애플리케이션에 의해 주도되는 어댑터이다.

  • 애플리케이션 코어가 입력, 출력 포트를 제공해야 어댑터와 통신이 가능하다.

  • 주도하는 어댑터의 입력 포트는 코어의 유스케이스 클래스 중 하나에 의해 구현된다.

  • 주도되는 어댑터의 출력 포트는 코어에 의해 호출되는 인터페이스가 되고, 이 출력 포트를 어댑터가 구현한다.

추가 자료

주니어 개발자의 클린 아키텍처 맛보기 | 우아한형제들 기술블로그

https://lkic1625.github.io/architecture/hexagonal_architecture/

Last updated