240703 실전 프로젝트 - DDD 세션

노재원·2024년 7월 3일
0

내일배움캠프

목록 보기
74/90

프로젝트는 아직 초기 단계라 기본적인 정책과 CRUD부터 구현해나가고 있다. 수준별 분반이 이루어진 조라서 이번엔 확실히 정책적인 측면에서 조금 더 다양한 측면을 고려해서 정하다 보니 대화의 흐름도 길어지게 되는 것 같지만 나름 재밌는 것 같다.

DDD 세션

튜터님의 사내 컨퍼런스로 비개발자도 들을 수 있게 개발용어가 줄어든 DDD에 대한 세션이 있으셨다고 해서 그걸 캠프에서 세션으로 진행해주셨다.

DDD의 개념을 이해하기란 굉장히 어렵다는 걸 Spring 입문할 때 느꼈으니 이참에 많은 프로젝트와 과제를 거쳐오면서 내가 이해하고 써왔는지 궁금한 내용이 있는지에 대한 정리를 진행했다.

DDD의 본질

DDD는 복잡한 도메인을 다뤄야 하는 소프트웨어 프로젝트에 박차를 가하는 것을 목표로 삼는 사고 방식이자 우선순위의 모듬이다. - DDD 서문

개개인마다 제품을 바라보는 사고방식이 달라진다는 점에서 다른 사고 방식을 간단한 구조로 통합하기 위해 적용한다.

DDD의 목표

  1. 소프트웨어 설계가 도메인 전문가와 개발자 간의 공동 작업을 통해 도메인 지식을 정확히 반영하도록 하는 것
  2. 복잡한 도메인 지식을 소프트웨어에 잘 반영하여 유지보수성과 확장성을 높이는 것

도메인

음식 배달의 프로세스를 정의한다면 메뉴 - 주문 - 조리 - 배달 - 결제 - 식사 같은 흐름들을 떠올릴 수 있다.

이 때 메뉴 - 주문 - 결제를 시스템으로 개발할 수 있는 도메인으로 정의할 수 있을 것이고 구조에 따라 조리, 배달, 식사도 도메인 영역 안에 포함할 수 있다.

모델

모델은 작게 생각하기 쉽지만 대체로 도메인 논리들까지 다 포함해서 대상의 단순화를 진행한 것이고 세부사항은 생략되어 있다.

도메인 모델

사용자가 도메인 안에서 문제를 해결할 때 필요하고 관련된 측면을 추상화하고 세부사항을 생략해 정리한 것이다.

도메인 모델은 설계 전부터 개발자와 도메인 전문가 사이의 활발한 논의를 거쳐 유용한 도메인 모델을 도출하는 지식 탐구 시간을 가질 수 있다.

도메인 전문가는 사업팀, 마케팅팀, 배달담당자등 많은 파트의 사람들이 도메인 전문가로 지식 탐구 시간을 개발팀과 논의를 거쳐 도메인 모델을 추출해낼 수 있다.

보편 언어 (ubiquitous language)
개발팀의 개발 용어는 도메인 전문가와 대화할 때 거리감이 있다. 장바구니를 Cart, 수량을 Quantity 처럼 표현하기 보다는 보편적으로 사용하는 언어로 미리 약속하고 대화하는 것이 좋다.

그래서 도메인 모델은 지속적으로 개발팀과 도메인 전문가간 논의를 통해 도메인 모델을 창조하고 발전시켜나가며 코드까지 변경하게 된다. 처음부터 뛰어난 도메인 모델을 만들어 내는 것보단 지속적인 발전을 요구하게 된다.

DDD 빌딩 블록

도메인 모델을 구성하기 위한 요소들을 어느정도 목적을 나누어 시스템 복잡도를 낮추는 데에 사용한다.

Entity

DDD가 말하는 Entity는 고유한 식별성을 가지고 해당 식별자로 동일성, 연속성을 유지할 수 있는 데이터다. 변경이 이루어지더라도 식별자를 통해 같은 Entity임을 확인할 수 있어야 하고 JPA가 말하는 Entity와 결과적으론 목적이 같지만 다루고자 하는 개념은 다르다.

Value object

식별성은 없지만 사물의 어떤 특성을 묘사하는데에 사용되는 객체다. 그렇기에 단순히 속성에 집중하고 속성 값을 통해 동등성을 판별할 수 있다.

예를 들어 커머스에서 Money 라는 값 객체를 다룬다면 내부적으로 amount (ex: 10,000), currency(ex: KRW) 로 객체의 속성에 대해서만 중요하고 개별적으로 식별할 필요가 없으면 값 객체로 분류하면 된다.

일반적으로 사용할 때 만원짜리 지폐 두 개가 서로 다른 금액이라고 판단 할 이유가 없다. 하지만 조폐공사가 지폐를 다룬다면 지폐의 고유한 식별값이 필요하므로 값 객체가 아닌 Entity로 설정되는 것이다.

Aggregate

일관된 변경을 보장하기 위해 하나의 단위로 처리하는 집합이다. 집합의 내부엔 관련 데이터로 Entity, Value object같은 데이터가 포함된다.

같은 Aggregate 내의 다른 객체들에 대한 접근과 변경은 Root entity를 통해 이루어진다.

그리고 Aggregate root는 외부에서 참조할 수 있는 유일한 객체가 된다. 커머스로 보자면 Product, Order가 Aggregate root가 될 수 있다고 생각할 수 있다.

Aggregate root의 선정

트랜잭션 범위 내에서 일관된 상태를 유지해야하는 단위로 잡는다. 일관된 상태를 유지하기 위한 값을 불변식으로 표현한다.

Order 내에 Address, Item 같은 정보가 있다면 서비스가 Order의 검증을 진행할 때 Order, Address, Item을 모두 사용하는게 아니라 Order만 사용하고 Order 내부에 Address, Item을 응집시켜 Order를 Aggregate root로 선정하는 것이다.

Repository

DDD에서 Repository는 Aggregate에서 사용하는 데이터들을 메모리에서 다루듯이 조회하고 저장할 수 있는 인터페이스를 말한다.

이는 데이터 저장소의 구체적인 접근 방식을 숨기고 도메인 모델이 데이터 저장소와 상호작용을 쉽게 하기 위함이다.

이전에 공부할 때도 다뤘듯 JpaRepository를 즉시 주입받는 것은 기술적 관심사에 크게 영향을 받으므로 POJO Repository Interface를 바라보게 만들어 데이터 저장소에 구체적으로 접근하기 위해 기술적 관심사에 영향을 받는 Data access layer의 분리가 있는 것이 좋다.

도메인 모델은 해당 방식에 대한 정보를 알 필요가 없어 추상화가 된다.

도메인 이벤트

도메인 모델 내에서 발생하는 사건들을 의미하고 중요한 상태 변화를 나타내며 이를 다른 시스템이나 다운스트림 시스템에서 처리할 수 있다. (EDA와 비슷한 개념)

이를 이용하면 EDA의 목적처럼 여러 Aggregate간 느슨한 결합과 각 서비스가 서로를 호출하지 않고 올바른 의존관계 방향성을 유지할 수 있다.

전략적 설계 (Bounded context)

위에서 다룬 내용들은 전술적 설계에 해당하는 부분이고 전략적 설계도 번외로 다뤄주셨다.

하나의 시스템을 여러개의 독립적인 컨텍스트로 나누어 관리하는 개념이다.

특정 도메인 모델이 유효한 경계가 되고 각 B.C. 내에서 도메인 모델은 일관성을 유지한다. 이렇게 경계를 명확히 하면 모델의 충돌을 피하고 독립적으로 모델을 발전시킬 수 있다.

한 번 B.C.를 설정하고 관계를 설정했다면 최대한 해당 경계를 유지하게 해야한다.

후기

DDD는 개념적인 부분에 새로운 용어가 정말 많아서 참 어려운 것 같다. 튜터님은 이런 방법론을 간단한 프로젝트에서도 적용하는 건 추가 비용이 발생하므로 모든 프로젝트에 적용할 필요가 없다고 하셨다.

어디 가서 DDD를 안다거나 DDD를 다뤄봤다고 얘기하기엔 여전히 터무니 없는 이야기지만 이런 식으로 한번씩 개념을 정리하고 넘어가니 조금조금씩 실루엣이 보이나 싶은 착각도 드는 것 같고 재밌는 세션 시간이 됐다.

0개의 댓글