Today I Learned

[도메인 주도 설계] 07. 언어의 사용(확장 예제) (1) 본문

도메인 주도 설계

[도메인 주도 설계] 07. 언어의 사용(확장 예제) (1)

하이라이터 2022. 1. 6. 01:08
728x90

예제를 통해 MODEL-DRIVEN DESIGN의 적용 효과와 어떻게 요구사항과 구현쟁점을 해결하는지 살펴보자.

 

화물 해운 시스템 소개

  • 초기 요구사항
    1. 고객 화물의 주요 처리상황 추적
    2. 화물 사전 예약
    3. 화물이 일정한 처리 지점에 도달할 때 자동으로 고객에게 송장을 발송
  • 해운 도메인 모델을 나타내는 클래스 다이어그램
  • 모델 내의 각 객체는 다음과 같은 의미를 지닌다.
    • Handling Event(처리이벤트) - Cargo에 불연속적으로 발생하는 활동(화물을 배에 적재, 세관을 통과 등등)
    • Delivery Specification(배송 명세) - 목적지와 도착 날짜를 포함한 배송 목표를 정의
      • Delivery Specification이 없다면 Cargo 객체에서 배송 목표를 명시하기 위한 모든 속성과 연관관계의 세부적인 의미를 책임져야 한다.
      • 추상화를 통해 전체적으로 모델을 설명할 때 세부사항을 쉽고 안전하게 감출 수 있다.
      • 더 표현력이 있다. Cargo의 정확한 배송 수단이 결정되지 않았지만 Delivery Specification에 명시된 목표는 는 반드시 달성해야 한다는 점을 명시적으로 드러낸다.
    • 역할(role) - 해운 과정에서 Customer가 수행해야 하는 여러 측면을 구분("선적인", "수취인", "지불인" 등)
    • Carrier Movement - 특정 Carrier에 의한 한 Location에서 다른 Location으로의 이동
    • Delivery History(배송 이력) - 실제 화물에 어떤 일이 발생했는지를 반영

도메인 격리 : 응용 기능 소개

  • 도메인의 책임이 시스템의 다른 부분과 섞이는 것을 방지하고자 LAYERED ARCHITECTURE를 적용해 도메인 계층을 구별해보자.
    1. Tracking Query(추적 질의) : 특정 화물의 과거와 현재 처리 상태에 접근
    2. Booking Applicat ion(예약 어플리케이션) : 새로운 Cargo를 등록하고 등록된 화물 처리를 준비
    3. Incident Logging Application(사건 기록 애플리케이션) : 각 Cargo의 처리 내역을 기록 (Tracking Query로 찾은 정보를 제공)

ENTITY와 VALUE OBJECT의 구분

  • Customer(고객) - Customer는 한 사람이나 회사를 나타내는 ENTITY이다. 고객 데이터베이스를 통해 고객의 ID를 할당한다.
  • Cargo(화물) - 각각의 화물에 해당하는 ENTITY이다. 화물 ID는 자동으로 생성되며, 예약 시 고객에게 전달된다.
  • Handling Event(처리 이벤트)와 Carrier Movement(운송수단 이동) - 개별 사건을 토대로 처리 상황을 알아낼 수 있다. 현실 세계의 사건은 개별로 존재하므로 ENTITY이다. 
    Carrier Movement는 해운 일정에서 획득한 코드로 식별되며, Handling Event는 Cargo ID, 완료시간, 화물 유형을 조합해서 식별할 수 있다.
  • Location(위치) - 경도, 위도같은 측정 수단보다는 해운 항로를 비롯한 도메인에 특화된 관심사에 따라 장소를 관련지을 수 있다. 따라서 임의의 내부 식별자만으로 충분하다.
  • Delivery History(배송이력) - Delivery History는 서로 대체할 수 없으므로 ENTITY에 해당하지만, 화물과 1:1 관계에 있으므로 자체적인 식별성은 없는 셈이다. Delivery History의 식별성은 그것을 소유하는 Cargo에서 가져온 것이다.
  • Delivery Specification(배송명세) - Delivery Specification은 Cargo의 목표를 나타내긴 하지만 Cargo에 의존하지는 않는다. 두 개의 Cargo가 동일한 곳으로 배송되는 중이라면 동일한 Delivery Specification을 공유할 수 있다.
    따라서 VALUE OBEJCT에 해당한다.
  • 역할과 그 밖의 속성 - 역할은 연관관계에 관한 사항을 전달하지만 이력이나 연속성을 지니지는 않는다. 따라서 역할은 VALUE OBJECT이다.
    시간/날짜나 이름 같은 그 밖의 속성도 VALUE OBJECT이다.

해운 도메인의 연관 관계 설계

  • 양방향 연관관계는 설계에서 문제를 일으킬 수 있다. 또한 탐색 방향은 모델 자체를 심층적으로 만들기도 한다.

AGGREGATE의 경계

  • Customer와 Location, Carrier Movement는 자체적인 식별성을 지니고 여러 Cargo 사이에서 공유되므로 자체적인 AGGREGATE의 루트가 되어야 한다. AGGREGATE에는 그것들의 속성을 비롯해 상세 수준의 다른 객체도 포함된다.
  • Cargo AGGREGATE는 특정 Cargo가 없다면 존재하지 않을 것들을 포함할 수 있다. Delivery History와 Delivery Specification, Handling Event가 이에 속한다.
  • Handling Event도 자체적인 AGGREGATE의 루트이다. Delivery History에 대한 Handling Event를 찾거나, Carrier Movement를 적재 및 준비하기 위한 활동을 찾는데 사용될 수 있다.

REPOSITORY의 선정

  • AGGREGATE의 루트인 ENTITY가 5개 있으므로 여기에 맞게 고려사항을 한정할 수 있다.
  • 어떤 것이 실제 REPOSITORY를 가져야하는지 결정하기 위해 애플리케이션의 요구사항을 되돌아볼 필요가 있다.
  • 화물을 예약하려면 다양한 역할(선적인 수하인 등)을 수행하는 Customer를 선택해야 하므로 Customer Repository가 필요할 것이다.
  • Cargo의 목적지를 지정하고자 Location을 찾아볼 필요가 있으므로 Location Repository도 만들어야 한다.
  • 사용자가 현재 Cargo에 적재되고 있는 Carrier Movement를 찾기 위해서는 Carrier Movement Repository가 필요할 것이다.
  • 어느 Cargo가 적재됐는지 시스템에 알려주기 위해서는 Cargo Repository도 필요하다.
  • Handling Event Repository는 아직 없다. 이는 Delivery와의 연관관계를 컬렉션으로 구현하기로 했고, 애플리케이션 요구사항에는 Carrier Movement에 적재된 것을 찾아야 한다는 요건이 없기 때문이다.

 

728x90
Comments