2. 아키텍처 개요
이 장에서 볼 내용
- 아키텍처
- DIP
- 도메인 영역의 주요 구성요소
- 인프라스트럭처
- 모듈
#
네 개의 영역- 아키텍처를 설계할 때 출현하는 전형적인 영역은 '표현', '응용', '도메인', '인프라스트럭처' 의 네영역입니다.
- 표현 영역은 사용자의 요청을 해석해서 응용 서비스에 전달하고 응용 서비스의 실행 결과를 사용자가 이해할 수 있는 형식으로 변환해서 응답합니다.
- 응용 영역은 도메인 모델을 이용해서 사용자에게 제공할 기능을 구현합니다. 실제 도메인 로직 구현은 도메인 모델에 위임합니다.
- 도메인 영역은 도메인 모델을 구현합니다. (핵심 로직을 도메인 모델에서 구현합니다.)
- 인프라스트럭처 영역은 구현 기술을 다룹니다.
#
계층 구조 아키텍처- 전체적인 아키텍처는 위 그림의 구조를 따릅니다.
- 계층 구조는 그 특성상 상위 계층에서 하위 계층으로의 의존만 존재하고 하위 계층은 상위 계층에 의존하지 않습니다.
- 인프라스트럭처에 의존하면 '테스트 어려움'과 '기능 확장의 어려움'이라는 문제가 발생합니다.
#
DIP- 고수준 모듈의 기능을 구현하려면 여러 하위 기능이 필요합니다.
- 고수준 모듈이 제대로 동작하려면 저수준 모듈을 사용해야 합니다.
- DIP는 이 문제를 해결하기 위해 저수준 모듈이 고수준 모듈에 의존하도록 바꿉니다.
- DIP를 적용해서 고수준 모듈이 저수준 모듈에 의존하지 않기 때문에 테스트 등이 쉬워집니다.
#
DIP 주의사항- DIP는 단순히 인터페이스와 구현 클래스를 분리하는 것이 아닙니다.
- 핵심은 고수준 모듈이 저수준 모듈에 의존하지 않도록 하는 것입니다.
#
DIP와 아키텍처- 인프라스트럭처 영역은 구현 기술을 다루는 저수준 모듈이며 응용 영역과 도메인 영역은 고수준 모듈입니다.
#
도메인 영역의 주요 구성요소도메인 영역의 주요 구성요소는 다음과 같습니다.
요소 | 설명 |
---|---|
엔티티(ENTITY) | 고유의 식별자를 갖는 객체 |
밸류(VALUE) | 고유의 식별자를 갖지 않는 객체로 주로 개념적으로 하나인 도메인 객체의 속성을 표현할 때 사용 |
애그리거트(AGGREGATE) | 애그리거트는 관련된 엔티티와 밸류 객체를 개념적으로 하나로 묶은 것 |
리포지터리(REPOSITORY) | 도메인 모델의 영속성을 처리 |
도메인서비스(DOMAIN SERVICE) | 특정 엔티티에 속하지 않은 도메인 로직을 제공 |
#
엔티티와 밸류- 도메인 모델 엔티티와 DB 테이블의 엔티티의 가장 큰 차이점은 도메인 모델의 엔티티는 데이터와 함께 도메인 기능을 함께 제공합니다.
- 또 다른 차이점은 도메인 모델의 엔티티는 두 개 이상의 데이터가 개념적으로 하나인 경우 밸류 타입을 이용해서 표현할 수 있다는 것입니다.
#
애그리거트- 도메인이 커질수록 개발한 도메인 모델도 커지면서 많은 엔티티와 밸류가 출현합니다.
- 애그리거트는 관련 객체를 하나로 묶은 군집입니다.
- 애그리거트는 군집에 속한 객체들을 관리하는 루트 엔티티를 갖습니다.
- 루트 엔티티는 애그리거트에 속해 있는 엔티티와 밸류 객체를 이용해서 애그리거트가 구현해야할 기능을 제공합니다.
#
리포지터리- 도메인 객체를 지속적으로 사용하려면 RDBMS, NoSQL, 로컬 파일과 같은 물리적인 저장소에 도메인 객체를 보관해야 합니다. 이를 위한 도메인 모델이 리포지터리입니다.
- 엔티티나 밸류가 요구사항에서 도출되는 도메인 모델이라면 리포지터리는 구현을 위한 도메인 모델입니다.
- 응용 서비스와 리포지터리는 밀접한 연관이 있습니다.
- 응용 서비스는 필요한 도메인 객체를 구하거나 저장할 때 리포지터리를 사용합니다.
- 응용 서비스는 트랜잭션을 관리하는데, 트랜잭션 처리는 리포지터리 구현 기술에 영향을 받습니다.
- 리포지터리는 응용서비스가 필요로 하는 메서드를 제공합니다.
- 애그리거트를 저장하는 메서드
- 애그리거트 루트 식별자로 애그리거트를 조회하는 메서드
#
요청 처리 흐름- 다음처럼 요청 처리 흐름이 진행됩니다.
#
인프라스트럭처 개요- 인프라스트럭처는 표현 영역, 응용 영역, 도메인 영어을 지원합니다.
- 도메인 객체의 영속성 처리, 트랜잭션, SMTP 클라이언트, REST 클라이언트 등 다른 영역에서 필요로 하는 프레임워크, 구현 기술, 보조 기능을 지원합니다.
- 그러나 인프라스트럭처에 대한 의존을 없애는 것이 좋은 것은 아닙니다.
- 구현의 편리함은 DIP가 주는 다른 장점(변경의 유연함, 테스트가 쉬움)만큼 중요하기 때문에 DIP의 장점을 해치지 않는 범위에서 응용 영역과 도메인 영역에서 구현 기술에 대한 의존을 가지는 것이 현명합니다.
- 표현 영역은 항상 인프라스트럭처 영역과 쌍을 이룹니다.
#
모듈 구성- 아키텍처의 각 영역은 별도 패키지에 위치합니다.
- 도메인이 크면 하위 도메인으로 나누고 각 하위 도메인마다 별도 패키지를 구성합니다.
- 도메인이 복잡하면 도메인 모델과 도메인 서비스를 다음과 같이 별도 패키지에 위치할 수도 있습니다.
com.myshop.order.domain.order
: 애그리거트 위치com.myshop.order.domain.service
: 도메인 서비스 위치
- 응용 서비스도 다음과 같이 도메인 별로 패키지를 구분할 수 있습니다.
com.myshop.catalog.application.product
com.myshop.catalog.application.category
- 모듈 구조를 얼마나 세분화해야 하는지에 대해 정해진 규칙은 없습니다.
- 가능하면 한 패키지에 10개 미만으로 유지하는 것이 좋습니다.