본문으로 건너뛰기

Layered-Architecture

1. Layered Architecture

  • 계층형 아키텍처는 웹 계층, 도메인 계층, 영속성 계층으로 구성된 전통적인 웹 애플리케이션의 구조입니다.
  • 계층형 아키텍처에서 전체적으로 적용되는 유일한 규칙은 특정 계층에서는 같은 계층 내의 컴포넌트나 하위 계층의 컴포넌트만 사용할 수 있다는 것입니다.

1.1 Web Layer

  • 웹 계층은 웹 요청을 받아 도메인 계층 또는 비즈니스 계층에 있는 서비스로 요청을 전달합니다.
  • 서비스로부터 응답을 받아 웹 응답을 반환합니다.

1.2 Domain Layer

  • 서비스와 도메인 엔티티로 구성된 계층입니다.
  • 서비스에서는 필요한 비즈니스 로직을 수행하고, 도메인 엔티티의 현재 상태를 조회하거나 변경하기 위해 영속성 계층의 컴포넌트를 호출합니다.

1.3 Persistence Layer

  • 영속성 계층은 도메인 엔티티의 현재 상태를 조회하거나 변경하기 위해 데이터베이스와 통신합니다.

2. 계층형 아키텍처의 구조

계층형 아키텍처는 다음과 같은 구조를 가집니다:

  • 웹 계층(Web Layer): 사용자 인터페이스와 외부 요청을 처리하는 최상위 계층입니다
  • 도메인 계층(Domain Layer): 비즈니스 로직을 담당하는 중간 계층입니다
    • 서비스(Service): 비즈니스 로직을 수행하는 컴포넌트입니다
  • 영속성 계층(Persistence Layer): 데이터베이스와 직접 통신하는 최하위 계층입니다
    • 엔티티(Entity): 도메인 객체를 표현하는 컴포넌트입니다
    • 리포지토리(Repository): 데이터 접근을 추상화하는 컴포넌트입니다

2.1 계층 간 의존성 방향

계층형 아키텍처에서는 다음과 같은 의존성 방향을 가집니다:

  • 웹 계층 → 도메인 계층 (서비스)
  • 도메인 계층 (서비스) → 리포지토리 계층 (엔티티, 리포지토리)

3 계층형 아키텍처의 문제점

3.1 데이터베이스 주도 설계의 문제점

  • 계층형 아키텍처의 의존성 방향은 데이터베이스 주도 설계를 유도합니다.
  • 하향식 의존성: 상위 계층이 하위 계층에 의존하면서, 결국 모든 계층이 데이터베이스 구조에 영향을 받게 됩니다.
  • 도메인 로직의 분산: 비즈니스 로직이 도메인 계층과 영속성 계층에 분산되어 응집도가 떨어집니다.
  • 테스트의 어려움: 데이터베이스에 의존적인 구조로 인해 단위 테스트가 복잡해집니다.
  • 변경의 어려움: 데이터베이스 스키마 변경 시 여러 계층에 걸쳐 수정이 필요합니다.

3.1.1 ORM과 영속성 계층의 특징

ORM 엔티티의 위치와 접근성
  • ORM에 의해 관리되는 엔티티들은 일반적으로 영속성 계층에 위치합니다
  • 계층은 아래 방향으로만 접근 가능하므로 도메인 계층에서 영속성 계층의 엔티티에 접근할 수 있습니다
  • 접근 가능한 엔티티는 필연적으로 사용되기 마련입니다
강한 결합의 발생
  • 영속성 계층과 도메인 계층 사이에 강한 결합이 생성됩니다
  • 서비스가 영속성 모델을 비즈니스 모델처럼 사용하게 됩니다
    • JPA로 관리하는 엔티티 모델에 비즈니스 로직이 혼재되어 있는 상황
  • 도메인 로직과 함께 영속성 계층 관련 작업들도 처리해야 합니다:
    • 즉시로딩(eager loading)
    • 지연로딩(lazy loading)
    • 데이터베이스 트랜잭션 관리
    • 캐시 플러시(flush) 처리
계층형 아키텍처 목표와의 모순
  • 영속성 코드가 도메인 코드에 혼재하게 됩니다
  • 한 계층만 독립적으로 변경하는 것이 어려워집니다
  • 계층형 아키텍처가 추구하는 유연성과 선택의 폭 확대 목표와 정반대 결과를 초래합니다

3.2 유스케이스가 숨겨집니다

계층 건너뛰기 현상

  • 계층형 아키텍처에서는 성능이나 편의성을 이유로 계층을 건너뛰는 현상이 자주 발생합니다.
  • 웹 계층 → 영속성 계층 직접 접근:
    • 웹 계층에서 도메인 계층을 거치지 않고 영속성 계층에 직접 접근하는 경우
    • 이때 웹 계층에 도메인 로직이 구현되어 비즈니스 로직이 분산됩니다.
    • 테스트 시 웹 계층과 영속성 계층을 모두 모킹해야 하므로 테스트 복잡도가 증가합니다.

도메인 로직 분산의 문제

도메인 로직이 여러 계층에 흩어지는 주요 원인들:

  • 웹 계층에서의 비즈니스 로직 구현:
    • 간단한 로직이라는 이유로 웹 계층에서 직접 처리
    • 점진적으로 복잡한 로직도 웹 계층에 축적
  • 엔티티 모델에서의 비즈니스 로직 혼재:
    • JPA 엔티티에 비즈니스 로직을 포함시키는 경우
    • 영속성 관심사와 비즈니스 관심사가 혼재되어 응집도 저하

유스케이스 가시성 문제

  • 비즈니스 로직이 여러 계층에 분산되면서 특정 유스케이스의 전체적인 흐름을 파악하기 어려워집니다.
  • 하나의 비즈니스 기능을 이해하기 위해 여러 계층의 코드를 동시에 살펴봐야 합니다.

3.3 서비스의 너비 제한이 없음

  • 계층형 아키텍처는 도메인 서비스의 너비에 관한 규칙을 강제하지 않습니다
  • 그렇기 때문에 시간이 지나면 여러 개의 유스케이스를 담당하는 아주 넓은 서비스가 생기게 됩니다.
  • 넓은 서비스는 영속성 계층에 많은 의존성을 가지며, 다시 웹 레이어의 많은 컴포넌트가 이 서비스를 의존하게 됩니다.
    • 이렇게 되면 서비스를 테스트하는 것이 어려워집니다.