도메인 주도 설계는 전체 서비스를 아우르는 수많은 기능 도메인을 각각의 바운디드 컨텍스트로 묶어내고, 각 바운디드 컨텍스트에서 통용되는 유비쿼터스 언어를 정의하는 전략적 설계와, 전략적 설계를 통해 식별된 각각의 바운디드 컨텍스트 (혹은 마이크로서비스)의 내부 구조를 상세하게 정의하고 비즈니스의 고유한 활동을 모델링하는 전술적 설계로 구성된다. 이 글에서는 전략적 설계를 다루도록 하겠다.
이 글을 작성하는 데 다음 유튜브 영상을 참고하였다.
ㄷㄷㄷ: Domain Driven Design과 적용 사례공유 / if(kakao)2022
우선 도메인 주도 설계의 특징에 대해서 먼저 언급하고 넘어가겠다.
어떤 개발자들은 도메인보다는 "데이터"에 집중한다. 그들은 Value Object 혹은 데이터베이스 Entity (주로 JPA를 사용하는 경향이 있다)를 우선적으로 정의하고, 비즈니스는 데이터에 종속적인 로직을 가지게 된다.
DDD에 입각한 개발자는 도메인을 중심으로 사고하고, 소프트웨어를 설계한다. 데이터보다는 기능적 문제 영역을 표현하는 도메인을 도출하려고 하고, 서로 연관된 도메인들을 바운디드 컨텍스트로 묶어내는 데 집중한다.
DDD에서 하나의 바운디드 컨텍스트 영역에서 통용되는 보편적인 언어를 사용해야 한다.
A: B 씨, 우리 이커머스 프로젝트에서요, 지금 물품 구매 기능 구현 B 씨가 담당하고 있죠?
B: 네, 그렇습니다. OO페이 API를 아이템 구매 기능 구현하는 데 사용하려고 합니다.
A는 물품이라는 용어를, B는 아이템이라는 용어를 사용하고 있다. 일상 대화에서는 문제가 없다. 그러나 하나의 바운디드 컨텍스트에서는 통일된 유비쿼터스 언어를 사용해야 한다.
"업무 용어를 통일하자"
분석/설계와 코드가 다른 구조가 아닌, 도메인 모델부터 코드까지 일관성 있는 구조의 모델을 추구한다.
전략적 설계를 설명하기 위한 예시 프로젝트를 소개하겠다.
두 사람을 짝지어주고, 일주일 동안 두 사람이 매일 번갈아가며 면접자와 피면접자가 되어 서로 스터디한 것에 대해 인터뷰를 함으로써 효과적으로 학습할 수 있도록 스터디를 매칭해 주는 플랫폼
프로필 기능
자동 매칭 시스템
스터디 진행상황 관리와 피드백
알림 및 리마인더 시스템
학습성과 리포트 및 대시보드
성과 인증 뱃지 및 레벨 시스템
바운디드 컨텍스트를 설명하는 데 있어, 서브도메인의 개념을 같이 설명해야 이 둘을 좀 더 잘 이해할 수 있을 것이다.
바운디드 컨텍스트는 범위다. 좀 더 자세히 말하자면, 바운디드 컨텍스트는 의미가 동일한 컨텍스트를 기준으로 나눈 소프트웨어 모델의 범위다. 하나의 바운디드 컨텍스트에 속한 소프트웨어 모델의 각 컴포넌트들은 그 범주 내에서 동일한 의미를 갖고 그 컨텍스트에 부합하는 일을 수행한다.
DDD는 범위를 한정지음으로써 하나의 바운디드 컨텍스트 안에 포함된 컴포넌트들의 응집도를 증진시키는 과정이다.
서브도메인이란 복잡한 단일 프로젝트를 여러 개의 도메인으로 쪼갬으로써 얻을 수 있다. 서브도메인은 프로젝트가 해결하고자 하는 거대한 도메인을 논리적으로 분리함으로써 생기는 하나하나의 분리된 도메인이다.
앞서 예시로 든 프로젝트 도메인을 다음과 같은 서브도메인으로 분리할 수 있다.
하나의 서브도메인에는 하나의 바운디드 컨텍스트가 존재하고, 하나의 바운디드 컨텍스트에는 하나의 서브도메인이 존재한다. 하나의 바운디드 컨텍스트에 여러 개의 서브도메인이 포함될 수 있지만, 이는 바람직한 설계가 아니다.
바운디드 컨텍스트를 통해 서브도메인을 나누는 과정은 문제 영역에 포함된다. 문제 영역이란 비즈니스의 주요 목표와 한계, 위험요소에 대해 논의하는 공간이다. 여기서 간단한 다이어그램을 사용하여 문제 영역을 가시화할 수 있다.
해결 영역은 문제 영역에서 논의한 사안에 대한 해결 방안을 구현하는 공간이다. 바운디드 컨텍스트 내에서 메인 소스, 테스트 소스 코드로 해결 방안을 개발한다.
하나의 바운디드 컨텍스트 안에서 협업하는 이해관계자들은 그 바운디드 컨텍스트에서 의미를 같는 통일된 언어로 서로 소통해야 한다. 이 언어는 팀 구성원들이 서로 소통할 때 사용된다.
유비쿼터스 언어는
위에 들었던 예시 프로젝트를 가지고 전략적 설계를 시험해 보겠다. 필자는 도메인 주도 설계를 막 입문했고 공부하고 있는 입장이기 때문에 여기서 나타나는 전략적 설계가 적절하지 않을 수도 있다.
이 프로젝트의 핵심 개념은 "스터디"다.
스터디는 "매칭"과 "데일리 스터디", "리마인더"를 가진다.
두 명의 "유저"가 각 매칭에 참여한다.
데일리 스터디는 "피면접자"로 선정된 사람이 공부하고 자신이 공부한 내용("포스트")를 공유하고, 이 내용을 가지고 "면접자"가 "피면접자"를 상대로 면접을 진행함으로써 이루어진다.
데일리 스터디가 종료된 이후, "면접자"는 "피면접자"에 대한 피드백을 남겨야 한다.
"리마인더"는 "매칭 알림", "블로그 글 작성 마감 기한 알림", "학습자료 업로드 알림", "피드백 작성 요청"을 가질 수 있다.
다이어그램으로 표현된 이 개념의 묶음은 "스터디"라는 서브도메인에 포함되며 하나의 바운디드 컨텍스트로 묶일 수 있다.
이 소프트웨어 모델의 "스터디", "매칭", "데일리 스터디"와 같은 각 컴포넌트들은 바운디드 컨텍스트 내에서 의미를 부여받고 비즈니스 로직을 수행한다.
유비쿼터스 언어는 여러 방법으로 개발할 수 있다. 유비쿼터스 언어를 개발하는 특별한 형식은 없지만, 유비쿼터스 언어 모델은 일관적으로 표현되어야 하며 모든 팀 구성원에게 똑같이 해석되어야 한다.
또한 유비쿼터스 언어는 명사만 정의해야 하는 건 아니다. 팀 내에서 소통할 때 동사 또한 조심스럽게 사용해야 한다.
유비쿼터스 언어의 일부만 러프하게 정의를 해 보겠다.
스터디에 참여하는 두 사람 사이에 있는 연결. 매칭에 참여하는 두 사람은 일정 기간 동안 서로 번갈아가며 면접자 혹은 피면접자가 되어 스터디를 진행한다.
피면접자로 선정된 사람이 하루 동안 공부한 내용을 정리한 것이며, 면접의 자료로도 사용된다. 블로그에 작성한 글, SCM 레포지토리에 push한 마크다운 문서, 노션 문서 등이 될 수 있다.
※ 지금 보니까 "학습자료"라는 용어와 충돌한다. "포스트"라는 말을 사용할지, "학습자료"라는 말을 사용할지 정해서 한 가지 말만 사용하는 게 바람직하다. 글을 쓰다 보니 실수가 발생했는데, 이걸 고치려면 스샷을 다시 찍어야 하니 귀찮다. 그냥 이대로 내버려 두겠다.
하루 동안의 공부를 나타내는 개념이다. 피면접자가 스스로 공부해서 포스트를 작성하고, 면접을 진행하는 과정을 포함한다.
이외에도 전략적 설계에 사용되는 도구가 더 있다. 컨텍스트 맵 등이 그러하다. 컨텍스트 맵과 같은 전략적 설계 도구와, 이후 단계인 전술적 설계에 대한 내용은 이후 글에서 다루도록 하겠다.