본문 바로가기

책리뷰/도메인 주도 개발 시작하기(DDD핵심 개념 정리부터 구현까지)

도메인 주도 설계 아키텍처

728x90
반응형

아키텍처 전형적인 네 가지 영역

  • 표현
  • 응용
  • 도메인
  • 인프라스트럭처

 

표현 영역

사용자의 요청을 받아 응용 영역에 전달하고, 응용영역의 처리 결과를 다시 사용자에게 보여주는 역할.

웹브라우저가 HTTP 요청 파라미터로 전송한 데이터를 응용서비스가 요구하는 형식의 객체 타입으로 변환해서 전달, 

응용서비스가 리턴한 결과를 JSON형식으로 변환해서 HTTP응답으로 웹브라우저에 전송 

 

 

 

응용 영역

시스템이 사용자에게 제공해야할 기능 구현. 도메인영역의 도메인 모델을 사용.

로직을 직접 수행하기보다 도메인 모델에 로직 수행을 위임함.

ex) 주문등록, 주문취소, 상품상세조회 

 

 

도메인영역

도메인모델 구현.

ex) 주문 도메인 '배송지 변경', '결제완료' 등 핵심 로직을 구현

 

 

인프라스트럭처영역

구현기술에 대한 것.

RDBMS 연동처리, 큐 구현, MongoDB나 레디스 연동 등 실제 구현을 다룸.

 

 

도메인영역, 응용영역, 표현영역은 구현기술을 사용한 코드를 직접 만들지 않고, 인프라스트럭처영역에서 제공하는 기능을 사용해서 필요한 기능을 개발함.

 

계층구조 아키텍처

 

상위 계층에서 하위 계층으로의 의존맨 존재, 하위계층에서 상위 계층 의존은 존재하지 않음.

 

 

DIP(의전역전 원칙)

 

  • 고수준모듈 : 의미있는 단일 기능을 제공하는 모듈
  • 저수준모듈 : 하위 기능을 실제로 구현한 것
  • 고수준 모듈이 제대로 동작하려면 저수준 모듈을 사용해야하지만 그럴 경우 
    '구현변경', '테스트어려움' 문제 발생 

 

public interface RuleDiscounter {
    public Money applyRules(Customer customer, List<OrderLine> orderLines);
}

public class CalculateDiscountService {
    private RuleDiscounter ruleDiscounter; // 룰 적용 객체
    
	  public CalculateDiscountService(RuleDiscounter ruleDiscounter) {
		    this.ruleDiscounter = ruleDiscounter; // 룰 적용 구현 객체를 생성자를 통해 전달받음.
    }

    public Money calculateDiscount(List<OrderLine> orderLines, String customerId) { 
        Customer customer = findCustomer(customerId);
        return ruleDiscounter.applyRules(customer, orderLines); 
    }

}

  • DIP를 적용하면 고수준 모듈이 저수준모듈에 의존하게됨
  • 추상화한 인터페이스이용해서 구현 기술 교체 > 생성자 주입으로 구현객체를 받아 구현
  • 테스트시 인터페이스에 Mock객체 생성하여 구현 테스트 진행 

 

 

도메인 영역의 주요 구성요소

  • 엔티티 
    • 고유 식별자를 갖는 객체, 자신의 라이프 사이클을 가짐 
  • 밸류
    • 고유의 식별자를 갖지 않는 객체, 개념적으로 하나인 값을 표현할 때 사용
  • 애그리거트
    • 연관된 엔티티와 밸류 객체를 개념적으로 하나로 묶은 것
  • 리포지터리 
    • 도메인 모델의 영속성을 처리함. RDBMS테이블에서 엔티티 객체를 로딩하거나 저장하는 기능 제공
  • 도메인서비스
    • 특정 엔티티에 속하지 않은 도메인 로직 제공 
엔티티와 도메인모델의 차이점
도메인모델의 엔티티는 데이터와 함께 도메인 기능을 제공한다.
예를 들어 주문을 표현하는 엔티티는 주문과 관련된 데이터 + 배송지주소 변경을 위한 기능 함께 제공 

 

애그리거트

관련 객체를 하나로 묶은 군집. 군집에 속한 객체를 관리하는 루트 엔티티를 갖는다. 

ex) 주문이라는 도메인 개념은 '주문','배송지 정보', '주문자', '주문목록','총결제금액'으로 구성 

 

 

리포지터리

물리적인 저장소에 도메인객체를 보관하기 위한 도메인모델

애그리거트 단위로 저장하고 조회한다.

응용서비스와 밀접한 연관이 있다.

  • 응용서비스는 필요한 도메인 객체를 구하거나 저장할 때 리포지터리 사용
  • 응용서비스는 트랜잭션을 관리하는데, 트랜잭션 처리는 리포지터리 구현 기술의 영향을 받음 

 

요청처리 흐름

사용자가 애플리케이션에 기능 실행 요청 > 표현영역 (데이터형식 검사) > 응용서비스에 실행 위임

> 응용 서비스(도메인 모델이용해서 기능 구현) > 리포지터리이용(저장or가져옴)

 

응용서비스는 도메인의 상태를 변경하기 위해 트랜잭션을 관리해야한다.

 

스프링은 @Transactional 애너테이션을 이용해 트랜잭션을 관리할 수 있다. 

 

인프라스트럭처 개요

인프라스트럭처는 표현영역, 응용영역, 도메인영역을 지원한다.

인프라스트럭처의 기능을 직접 사용하는 것보다 도메인, 응용 영역에서 정의한 인터페이스를 

인프라스트럭처 영역에서 구현하는 것이 시스템을 더 유연하고 테스트하기 쉽게 만들어준다. 

 

무조건 인프라스트럭처에 대한 의존을 없앨 필요는 없다.

@Transactional 한줄이면 트랜잭션 처리가 가능한데 스프링에 의존을 없애려면 스프링 설정을 사용해야 한다.

 

 

모듈 구성

도메인이 크면 하위도메인으로 나누고 각 하위도메인마다 별도 패키지를 구성할 수 있다.

 

모듈구조를 얼마나 세분화 해야하는지에 대해 정해진 규칙은 없다.

한 패키지에 10~15개 미만으로 타입 개수를 유지.

 

 

 

 

출처 : 도메인주도개발시작하기 (최범균저)

728x90
반응형