DDD - 도메인 모델 패턴


이 포스트에서는 DDD 에서 복잡한 비즈니스 로직을 구현하는 방식인 도메인 모델 패턴에 대해 알아본다.

DDD - 트랜잭션 스크립트 패턴, 액티브 레코드 패턴 의 트랜잭션 스크립트 패턴과 액티브 레코드 패턴은 비교적 간단한 비즈니스 로직을 다루는 패턴인데 반해, 도메인 모델 패턴은 복잡한 비즈니스 로직을 다루는 패턴이다.


목차


1. 도메인 모델

도메인 모델 패턴은 복잡한 비즈니스 로직을 다루기 위한 것이다.
CURD 인터페이스 대신 복잡한 상태 전환이나 항상 보호해야 하는 규칙인 비즈니스 규칙과 불변성을 다룬다.

아래는 이번 포스팅에서 다룰 가상의 헬프데스크 시스템의 요구 사항이다.

  • 고객은 직면한 문제를 설명하는 지원 티켓을 엶
  • 고객과 지원 할당된 에이전트 모두 메시지를 추가하고, 모든 내용은 지원 티켓에서 관리됨
  • 각 티켓은 낮음/중간/높음/긴급의 우선 순위를 가짐
  • 에이전트는 티켓의 우선 순위에 따른 응답 제한 시간(SLA, Service Level Agreement) 내에 해법을 제시해야 함
  • 할당된 에이전트가 응답 제한 시간 내에 응답 제한 시간 내에 응답하지 못하면, 고갯은 티켓을 에이전트의 상위 관리자에게 보고할 수 있음
  • 티켓이 상위 관리자에게 보고되면 에이전트의 응답 제한 시간이 33% 줄어듬
  • 에이전트가 상부 보고된 티켓의 응답 제한 시간의 절반이 지나기 전에 티켓을 열람하지 않으면 자동으로 다른 에이전트가 할당됨
  • 할당된 에이전트의 질문에 고객이 7일 이내에 응답하지 않으면 티켓은 자동으로 닫힘
  • 상부 보고된 티켓은 자동 혹은 할당된 에이전트에 의해 닫힐 수 없고, 고객 또는 에이전트의 매니저만 닫을 수 있음
  • 고객은 티켓이 닫힌 지 7일 이내에 닫힌 티켓을 다시 열 수 있음

위와 같은 요구 사항은 다양한 규칙들 속에서 서로 의존성을 형성하고, 모든 규칙은 지원 티켓의 수명 주기 관리 로직에 영향을 준다.
CRUD 데이터 입력처럼 간단하지 않기 때문에 액티브 레코드 객체를 사용하여 로직을 구현하면 로직이 중복되거나, 일부 비즈니스 규칙이 잘못 구현되어 시스템의 상태를 손상시킬 수 있다.


2. 구현

도메인 모델은 행동(behavior) 과 데이터, 모두를 포함하는 도메인의 객체 모델이다.

함수형 프로그래밍과 객체 지향 프로그래밍의 차이점에 대해서는 1.1.3. 함수형 프로그래밍 vs 객체 지향 프로그래밍 을 참고하세요.

DDD 의 전술 패턴인 애그리거트, 밸류 오브젝트, 도메인 이벤트, 도메인 서비스 모두 객체 모델의 구성 요소이다.


2.1. 복잡성

도메인 비즈니스 로직 자체로도 복잡하기 때문에 모델링에 사용되는 객체는 모델에 조금이라도 우발적인 복잡성을 추가하면 안된다.

모델에는 DB, 외부 시스템 구성 요소의 호출 구현 같은 인프라 or 기술적인 관심사가 포함되면 안된다.
이런 제약을 따르면 모델의 객체는 Plain Old Object 가 된다.
플레인 올드 오브젝트는 인프라 구성 요소나 프레임워크에 의지하지 않고 비즈니스 로직을 구현하는 객체이다.


2.2. 유비쿼터스 언어

도메인 모델의 객체가 기술적 관심사가 아닌 비즈니스 로직에 집중하면 바운디드 컨텍스트에서 사용하는 유비쿼터스 언어의 용어를 따르기 쉬워진다.


3. 구성요소

밸류 오브젝트, 애그리거트, 도메인 서비스와 같이 DDD 에서 제공하는 도메인 모델의 구성 요소와 전술적 패턴에 대해 알아본다.


3.1. 밸류 오브젝트(밸류 타입)

4.3. 밸류 타입 을 참고하세요.


3.2. 엔티티

4. 엔티티와 밸류 를 참고하세요.


3.3. 애그리거트

애그리거트는 엔티티이다.(엔티티는 단독으로 구현하지 않고 애그리거트 패턴의 컨텍스트에서만 엔티티를 구현함)
즉, 명시적인 식별 필드가 필요하고, 인스턴스의 생애 주기동안 상태가 변할 것으로 예상된다.


3.3.1. 일관성 강화

2.1. 도메인 규칙과 일관성 을 참고하세요.


3.3.2. 트랜잭션 경계

DDD - 애그리거트의 트랜잭션, 선점 잠금, 비선점 잠금, 오프라인 선점 잠금 을 참고하세요.


3.3.2.1. 엔티티 계층

4.2. 애그리거트 (Aggregate) 를 참고하세요.


3.3.2.2. 다른 애그리거트 참조

4. 애그리거트 참조 를 참고하세요.


3.3.2.3. 애그리거트 루트

2. 애그리거트 루트 를 참고하세요.


3.3.6. 도메인 이벤트

2.3.1. 한 트랜잭션에서 여러 애그리거트 수정: 도메인 이벤트 를 참고하세요.


3.4. 도메인 서비스

DDD - 도메인 서비스 를 참고하세요.


4. 복잡성 관리

밸류 타입의 상태 관련된 모든 비즈니스 로직은 자신의 경계 안에 있다.
애그리거트도 마찬가지로 자신의 메서드를 통해서만 수정된다.

비즈니스 로직은 비즈니스 불변성을 감싸고 보호하여 결국 자유도를 줄여준다.


정리하며..

도메인 모델 패턴의 3개의 구성 요소

  • 밸류 타입(밸류 오브젝트)
    • 값만으로 식별되는 비즈니스 도메인 개념이므로 명시적인 ID 식별자가 필요없음
    • 필드 중 하나가 변경되면 의미상 새로운 값을 생성하므로 밸류 오브젝트는 불변임
  • 애그리거트
    • 트랜잭션 경계를 공유하는 엔티티의 계층임
    • 트랜잭션 경계의 역할을 하므로 내부 객체를 포함한 모든 데이터는 원자적인 단일 트랜잭션으로 커밋되어야 함
    • 애그리거트의 상태와 내부 객체는 애그리거트의 커맨드를 실행하여 public 인터페이스를 통해서만 수정 가능함
    • 애그리거트와 관련된 모든 비즈니스 로직이 경계 내에 존재하도록 외부 컴포넌트는 애그리거트 내의 데이터 필드를 읽을 수만 있게 해야 함
    • 애그리거트는 도메인 이벤트를 게시하여 외부 엔티티와 통신 가능
  • 도메인 서비스
    • 비즈니스 로직을 담는 상태가 없는 객체

참고 사이트 & 함께 보면 좋은 사이트

본 포스트는 블라드 코노노프 저자의 도메인 주도 설계 첫걸음을 기반으로 스터디하며 정리한 내용들입니다.






© 2020.08. by assu10

Powered by assu10