진짜 개발자
본문 바로가기

Software Engineering/DDD (Domain Driven Design)

DDD - 도메인 모델 변경 과정 정리

728x90
Tour-cash 도메인 모델 변경 v1(카드, 분실 분리)

도메인 모델 변경

도메인 모델은 처음부터 완벽하게 구현하기가 무척 어렵습니다. 거의 불가능에 가깝다고 책에도 소개됩니다. 따라서 처음에는 개요를 알 수 있는 수준으로 개념모델을 구현하고, 운영하며 얻게되는 도메인 지식을 바탕으로 점차 구현모델에 가깝게 변형해 나가야 합니다.

 

이번 포스팅에서는 서비스를 운영하며 얻게된 지식을 바탕으로 도메인 모델을 변경한 것을 정리해보려고 합니다.

 

 

 

 

서비스 소개

업무 기밀이 누설 될수도 있는 관계로 서비스의 대략적인 설명만을 적겠습니다.


 1. 외국 고객에 대한 환급 서비스입니다.

 2. 고객은 지급된 카드를 통해 결제를 하며, 카드 사용내역을 확인할 수 있습니다.

 3. 사용내역에서 환급받고 싶은 물품을 선택하여 관리자에게 환급요청을 할 수 있습니다.

 4. 환급처리가 완료되면 공항에서 환급금을 받아 출국합니다.

 

 

 

 

1. 1차 변경

CardEntity , LossEntity를 별도의 애그리거트로 분리

 

 

 

1.1 변경전

객체 수준에서 서비스를 바라보면, 작은 부분에 집중되기 마련입니다.

따라서, 우선 도메인 모델을 변경하기전, 애그리거트 수준에서 서비스를 파악하는 것이, 변경하는데에 도움이 됩니다.

 

  • 카드 애그리거트Loss(분실도메인)을 포함하고 있습니다.

 

 

1.2 변경후

  • 분실 애그리거트를 별도로 구분하였습니다.
  • LossCard를 통해 분실된 Card를 참조합니다.

 

 

 

변경 이유

  • Card 루트 애그리거트가 생성될 때, 분실관련 정보는 같이 생성되지 않습니다.

  • 생성 주체가 다릅니다.

    => 분실은, 사용자의 요청에의해 생성이 되며, 카드는 관리자의 요청에의해 생성이됩니다.

 

 

 

 

 

 

2. 2차 변경

2.1 변경전


기존 구성이유

위의 도메인 모델에서 User의 모델 개념과 맞지 않음에도 Card를 소유하게 만든이유는, User가 Card를 등록 및 반납을 여러번 한 경우, 즉 여행을 여러번 와서 여러차례 카드를 사용했던 경우, 유저가 현재 등록한 카드를 구분하기가 어려웠기 때문입니다.

 

따라서 User가 현재 등록한 Card를 지정함으로써 이를 해결하려 했습니다.

 

 

 

2.2 변경후

  • User 애그리거트에서, Card를 삭제하였습니다.
  • Card의 Owner(id)를 통해서 User와 연결하도록 변경하였습니다.

 

 

변경 이유

  • User 애그리거트는 회원에 관련된 데이터만을 포함해야 합니다. 즉, Card관련 정보를 가지고 있는것은 옳지 않습니다.
  • id를 통해 연관관계를 맺을시, 탐색을 통한 오용을 방지할 수 있으며, 추후 서버의 확장에도 용이합니다. 또한 애그리거트 로딩전략등의 성능 고민을 하지 않아도 됩니다.

 

 

 

변경하기전 문제점!

하지만 변경전의 기존구성 이유에서 알 수 있듯이, CardRepository에서 User가 현재 등록한 카드 단 한개만을 구분하여 가져올 수 있는 방법이 필요합니다.

 

 

 

해결방법 1

card를 모두 사용하고, 환급을 받은 뒤 사용자는 카드를 반납하고 출국을 하게됩니다. 따라서 Card는 항상 단한개만이 등록된 상태를 유지하게 됩니다.

 

이 점을 이용하여, CardRepository에서, owner id(사용자 id)와, CardStatus(카드 상태)를 이용하여 가져옵니다.

 

 

문제점

비즈니스상, Card의 반납은 자유롭습니다. 즉, 사용자는 환급만을 받고 카드는 반납하지 않고 출국할 수 있습니다. 때문에, 등록된 상태의 카드가 2개이상이 존재할 수 있습니다.

 

 

 

해결방법 2

앞선 문제의 해결방법으로, Card Repository에서, User의 Id를 이용해 가져오되, 날짜의 역순으로 정렬한뒤 가장 최신의 한row만을 추출함으로써, 현재 등록된 카드를 가져오도록 했습니다.