[도메인 주도 개발 시작하기]2. 아키텍처 개요
https://product.kyobobook.co.kr/detail/S000001810495
도메인 주도 개발 시작하기: DDD 핵심 개념 정리부터 구현까지 | 최범균 - 교보문고
도메인 주도 개발 시작하기: DDD 핵심 개념 정리부터 구현까지 | 가장 쉽게 배우는 도메인 주도 설계 입문서!이 책은 도메인 주도 설계(DDD)를 처음 배우는 개발자를 위한 책이다. 실제 업무에 DDD를
product.kyobobook.co.kr
Chapter 1_도메인 모델 시작하기: https://inhyeok-blog.tistory.com/55
Chapter 2_아키텍처 개요 : https://inhyeok-blog.tistory.com/56
Chapter 3_애그리거트 :
Chapter 4_리포지터리와 모델 구현 :
Chapter 5_스프링 데이터 JPA를 이용한 조회 기능 :
Chapter 6_응용 서비스와 표현 영역 :
Chapter 7_도메인 서비스 :
Chapter 8_애그리거트 트랜잭션 관리 :
Chapter 9_도메인 모델과 바운디드 컨텍스트 :
Chapter 10_이벤트 :
Chapter 11_CQRS :
이러한 아키텍처는 아주 익숙하다. 기존에 사용하던 Controller-Service-Repository(표현-응용-인프라)로 이어지는 흐름과 비슷하다. 다만 여기서 도메인이 Data Object에서 그치지 않고 비즈니스 로직을 수행하는 하나의 계층으로 떠오른 것뿐이다. 그리곤 응용(Application)에서는 대부분의 기능을 도메인에게 위임한다.
앞서 보여준 구조는 이 그림과 같은 계층구조를 가지고 있다. 그리고 계층구조의 특성상 상위 계층은 하위계층을 의존하지만(구현의 편의를 위해 응용이 인프라를 의존하기도 한다), 하위 계층은 상위 계층을 모른다. 이 방식은 상위 계층이 하위계층의 구현에 의존한다는 것을 의미한다(즉, 인터페이스가 아니라 클래스에 의존한다). 그 이유는 하위계층의 인터페이스는 상위계층에 속하기 때문인데, 이에 대한 자세한 설명은 아래에서 설명하겠다. 하지만 이러한 방식은 두 가지 문제점을 가진다.
- 의존하는 하위 계층의 객체가 구현되기 전까지 상위 계층의 객체를 테스트하기 어렵다.(테스트의 어려움)
- 구현 방식을 의존하기 어렵다.(기능확장의 어려움)
이를 해결하기 위해서 DIP(Dependency Inversion Principle)를 소개한다.
바로 이렇게 하면 된다. 이것이 바로 DIP, 즉, 의존 역전 원칙이다. 이제 DIP를 통해서 앞서 말한 두 가지의 문제를 해결할 수 있다. 이때 주의해야 할 점이 있다. 바로 Interface만 만든다고 다 저수준이 되는 것은 아니라는 것이다. 인터페이스를 도출할 때 고수준의 DroolsRuleDiscounter의 관점에서 도출하는 것이 아니라, CalculateDiscountService에서 메시지 목록을 추출하는 것이 중요하다.
이제 도메인 영역의 주요 구성요소를 살펴보자.
- 엔티티(ENTITY)
- 고유 식별자를 갖는 객체로, 자신의 라이프 사이클을 갖는다.
- 도메인의 고유한 개념을 표현한다.
- 도메인 모델의 데이터를 포함하며 해당 데이터와 관련된 기능을 제공한다.
- 벨류(VALUE)
- 식별자를 가지지 않는다.
- 개념적으로 하나인 값을 표현할 때 사용된다.
- 엔티티의 속성뿐만 아니라 다른 벨류의 속성이 될 수도 있다.
- 애그리거트(AGGREGATE)
- 연관된 엔티티와 밸류 객체를 개념적으로 하나로 묶은 것이다.
- 속한 객체들이 동일한 라이프 사이클을 가진다.
- 리포지터리(REPOSITORY)
- 도메인 모델의 영속성을 처리한다.
- 도메인 서비스(DOMAIN SERVICE)
- 특정 엔티티에 속하지 않은 도메인 로직을 제공한다.
인프라스트럭처는 표현 영역, 응용 영역, 도메인영역을 지원한다. 그리고 앞서 말한 것 처럼 DIP를 활용해서 테스트의 어려움과 기능 확장의 어려움을 해결할 수 있었다. 하지만 인프라스트럭처를 활용하는 모든 상위 계층 객체가 완벽히인프라스트럭처의 구현에 의존하지 않도록 하겠다는 생각은 적절하지 않다. 이는 자칫 구현을 더 복잡하고 어렵게 만들 수 있기 때문이다. 가장 대표적이 예시가 바로 @Table, @Transactional 등의 어노테이션이다. 스프링에 대한 의존을 없애려면 복잡한 스프링 설정을 사용해야 한다.
이제 도메인 주도 개발을 했을 때의 모듈 구성을 살펴보자. 기본적으로 애그리거트별로 모듈을 만들고 하위 모듈로 UI(표현)-application(응용)-domain(도메인)-infrastructure(인프라)로 나눈다.
각 도메인 안에 하위 도메인을 하위 모듈로 둘 수도 있고, Command와 Query를 분리하기도 하는 등 다양한 확장요소가 있다.
하지만 자세한 내용을 코드를 보면서 이해하는 것이 가장 빠르므로, 마지막으로 이 책에서 설명하는 코드가 들어있는 GIthub Repositorty를 공유하고 글을 마친다. 모듈은 잘 만들어진 예시를 보면서 이해하는 것이 가장 효과적일 것이다.
Github Link: https://github.dev/madvirus/ddd-start2(에디터 모드 - Github Login 필요)
Github Repo: https://github.com/madvirus/ddd-start2(Repository - Github Login 미필요)