본문 바로가기
프로그래밍/도메인주도개발

도메인 주도 설계 핵심 정리

by 방구석개발자 2022. 7. 20.
반응형

1장 나에게 도메인 주도 설계는

좋은 설계와 나쁜 설계

작업보드 일정관리

스크럼의 가장 중요한 원칙 중 하나인 지식획득은 감안하지 않고 주로 일정 관리를 위해 스크럼을 사용하는 경우로, 정해신 일정 내에 소프트웨어 릴리스를 인도해야하는 압박감으로 인해 자주 발생한다.

DDD를 통하여 밑의 다양한 비즈니스 문제를 해결 할 수 있다.

  • 소프트웨어 개발을 이익중심이 아닌 원가 중심으로 생각한다.
  • 문제를 신중하게 연구하고 설계하기보다는 기술적으로 해결하려고 한다.
  • 데이터베이스에 너무 큰 우선순위를 부여 한다.
  • 개발자가 비즈니스 목적에 따라 클래스와 오퍼레이션 이름을 짓는 것에 크게 관심이 없다.
  • 일반적으로 비즈니스와 협업이 빈약하기 때문에 나온 문제다.
  • 프로젝트에 대한 예측을 매우 강하게 요구한다.
  • 개발자가 비즈니스 로직을 사용자 인터페이스 컴포넌트와 영속성 컴포넌트 안에 담는다.
  • 문법에 어긋나고 느리거나 권한이 없어 차단되는 데이터베이스 쿼리들이 사용자의 비즈니스 업무를 방해한다.
  • 구체적인 비즈니스 대신 상상 속 미래의 요구를 모두 고려해서 잘못된 추상화가 존재한다.
  • 오퍼레이션을 수행하는 서비스가 또 다른 서비스를 직접 호출하는 강하게 결합된 서비스가 존재한다.(유지보수하기 어려움)

5명의 개발자가 설계없이 프로젝트를 진행하면 5개의 서로 다른 설계가 하나로 뭉뚱그려진 것을 만들 뿐이다.

도메인 전문가의 혜택을 받자.

심사숙고한 설계로 소프트웨어를 제작하는 것이 비쌀 것 같아서 두렵다면, 앞으로 얼마나 계속 그 시스템을 사용해야 하고, 더 나아가 나쁜 설계를 수정해야 하는 것에 얼마나 더 큰 비용이 들 것인지 생각해야 한다.

좋은 것과 효과적인 것은 밀접한 관련이 있다.

스크럼에서 지식 획득은 실험과 협업 학습을 통해 이루어지며 이를 정보 구입 이라고도 한다. 지식은 절대 공짜가 아니다.

전략적 설계

세세한 구현에 앞서 비즈니스상 전략적으로 중요한 것, 중요도에 따라 일을 나누는 방법, 필요에 따라 통합하는 최적의 방법을 강조한다.

바운디드 컨텍스트라는 전략적 설계 패턴을 사용해서 도메인 모델을 분리하는 방법부터 배울 것이다.

DDD에 매우 중요한 전술적 설계 도구들 → 엔터티와 객체(Value Object)를 알맞은 크기의 애그리게잇으로 묶는 데 사용하는 애그리게잇 패턴이다.

도메인 이벤트의 사용은 명확하게 모델링하는 것을 도와주면서, 도메인에 발생한 것에 대해 알아야 하는 내용을 시스템과 공유하는 것을 돕는다. 공유할 대상이 로컬의 바운디드 컨텍스트 일 수도, 다른 원격의 바운디드 컨텍스트 일 수도 있다.

학습 과정과 지식의 정제

DDD는 지식을 더욱 발전시킬 수 있도록 생각하는 법을 알려준다. 이 목표를 돕는 부가적인 도구들도 있고, 7장'가속화와 관리도구'에서 확인 할수 있다.


2장 바운디드 컨텍스트 및 보편언어와 전략적 설계

DDD는 주로 명확하게 바운디드 컨텍스느 내에서 보편언어를 모델링하는 것에 대한 것이다.

바운디드 컨텍스트는 의미적으로 동일한 컨텍스트의 범위를 표현한다. 즉 특정한 일을 수행한다는 의미다.

바운디드 컨텍스트가 조직의 핵심 전략적 계획으로 개발되고 있을 때, 이를 핵심 도메인이라고 부른다.

기업의 올바른 전략적 결정을 위해 무엇이 핵심 도메인이어야 하고, 어떤 것을 제외시켜야 하는지 현명하게 선택해야 한다.

팀의 누군가가 보편 언어 표현을 사용하면, 팀 모두가 그 표현이 가진 제약사항과 정확한 의미를 이해한다.

하나의 바운디드 컨텍스트한 팀이 수행한다는 것은 특히 중요하다.

바운디드 컨텍스트를 사용하지 않을때 각 팀들은 더 많은 개념을 계속 추가하고 점점 큰 진흙 덩어리를 만들게 된다.

DDD는 서로 다른 개념들을 각기 다른 바운디드 컨텍스트 안으로 분리해 놓음으로써 개념 간 차이를 더욱 중시한다.

DDD의 2가지 도구로 함정을 피하는 데 도움을 줄 수 있다.

바운디드 컨텍스트와 보편언어다.

바운디드 컨텍스트: 핵심이 무엇인가 라는 질문에 답하도록 유도한다.

전략적 계획의 핵심이 되는 모든 개념들을 밀접하게 유지하면서 포용해야하고, 나머지는 모두 제외시켜야 한다.

바운디드 컨텍스트에 남은 개념들은 팀이 사용하는 보편언어의 일부가 된다.

엄격하게 핵심만 걸러낸 후 살아남은 개념들은 해당 바운디드 컨텍스트를 소유하는 팀의 보편언어 일부가 된다.

이를 위해서는 도메인전문가 + 소프트웨어 개발자를 하나로 묶어 서로 협업하는 팀을 만들어야 한다.

기술적 복잡도가 아닌 비즈니스 복잡도에 집중하라.

DDD의 또 다른 측면인 핵심 도메인 에서는 필수적인 모델 요소까지만으로 제한하는 것에 관심이 있기 때문이다.

결국엔 코드가 모델이고 모델이 코드다.

아마 작성된 시나리오를 팀의 명세서와 비교해 어떻게 도메인 모델을 검증하는 데 사용할 산출물로 전환시킬 수 있을지 궁금할 것이다. 사례를 통한 명세라고 불리는 기술이 있다. 이를 행위 주도 개발 이라고도 부른다.

아키텍처

바운디드 컨텍스트 안에는 무엇이 있는가? 도메인 모델 이상의 다양한 요소들로 구성된다. 이런 레이어들은 거의 모든 바운디드 컨텍스트 내에 존재한다.

기술은 아키텍처 전반에 걸쳐 산재해 있지만, 도메인 모델은 기술로부터 최대한 자유로워야 한다. 예를 들면 트랜잭션은 애플리케이션 서비스에 의해 관리되는 것이지, 도메인 모델에 의해 관리되는 것은 아니다.

3장 서브도메인과 전략적 설계

서브 도메인은 무엇인가?

간단하게 서브도메인은 전체 비즈니스 도메인의 하위 부분이다.

거대하고 복잡한 프로젝트에서 문제 영역을 이해할 수 있도록 전체 비즈니스 도메인을 논리적으로 쪼개는 데 서브도메인을 사용할 수도 있다.

서브도메인의 유형

  • 핵심도메인: 보편언어를 신중하게 만들기 위한 전략적 투자 영역이며 가장 큰 투자가 필요하다.
  • 지원 서브도메인: 이미 존재하는 제품으로 해결할 수 없는 맞춤 제작 개발이 필요한 모델링 영역을 말한다.
  • 일반 서브도메인:이 영역은 기존 제품 구매를 통해 바로 충족시킬 수 있는 경우에 해당한다.

복잡성 다루기

핵심 도메인 프로젝트에 어떤 영향을 주고 있는지는 명확히 해야 한다.

문제 영역에 대해 논의하기 위한 도구로 서브도메인을 사용해야 한다.


4장 컨텍스트 매핑과 전략적 설계

핵심 도메인을 다른 바운디드 컨텍스트와 통합해야 한다는 것도 배웠다. DDD에서는 이런 통합을 컨텍스트 매핑이라고 한다.

서로 다른 두 바운디드 컨텍스트 안에 각각의 보편언어가 있는 것을 생각해보면, 이 선은 두 언어 사이의 통역을 나타낸다.

각팀은 하나의 바운드 컨텍스트를 책임진다. 두 팀 사이에 파트너십을 구성한다.

  • 공유커널 관계
  • 고객-공급자 관계
  • 준주자 관계
  • 반부패 계층 : 가장 방어적인 컨텍스트 매핑 관계인데, 두 팀 사이를 번역하는 번역가를 고용한 것에 가까운 상황이다.
  • 공개 호스트 서비스: 일련의 서비스처럼 바운디드컨텍스트에 대한 접근을 제공하는 프로토콜이나 인터페이스를 정의한다.

공표된 언어: 바운디드 컨텍스트 규모에 관계없이 모두 간단한 사용과 번역을 가능하게 하는 문서화된 정보 교환 언어다.

각자의 길: 1개 이상의 바운디드 컨텍스트를 통합한 것이다.

큰 진흙 덩어리: 모두 다 합친것

컨텍스트 매핑 활용하기

바운디드 컨텍스트를 통합하려고 할때 여러 기술들이 있다. 그중에서 데이터베이스 통합은 진짜 피해야 한다.

그래도 통합을 강요받는 상황이 된다면 반부패 계층을 사용해서 모델을 독립시켜야 한다.

  • soap을 이용한 rpc
  • 레스트풀 http
  • 메시징

컨텍스트 매핑 사례

바운디드 컨텍스트들은 어떻게 각 컨테스트와 통신을 할까?

계약 - 청구 - 검사 각 컨텍스트가 있다면

정책발행이라는 이름으로 도메인 이벤트를 발생시킬 수 있다. 메시징 구독을 통에 다른 바운디드 컨텍스트들이 이 도메인 이벤트에 반응할때, 구독 바운디드 컨텍스트 안에 이 정책에 상응하는 정책 컴포넌트를 만들 수도 있다.


5장 애그리게잇과 전술적 설계

바운디드 컨텍스트 안에 자리잡은 개념들에 대해 알아보자.

이 개념들은 모델 안에 존재하는 애그리게잇들이다.

왜 필요할까?

바운디드 컨텍스트 안에는 애그리게잇과 값객체(ValueObject)가 있다.

엔터티는 독립적인 것이다.
엔터티는 같은 형태를 띠거나 다른 엔터티들과의 특성을 구별할 수 있는 고유한 식별성을 갖는다.

애그리게잇은 1개이상의 엔터티로 구성되고, 그중 한 엔터티는 애그리게잇 루트라고 부른다.

각 애그리게잇은 일관성 있는 트랜잭션 경계를 형성한다.

이것은 트랜잭션 제어가 데이터베이스에 커밋될 때, 한 애그리게잇 내의 모든 구성 요소는 반드시 비즈니스 규칙을 따르면서 일관성 있게 처리된다는 것을 의미한다.

트랜잭션 경계를 두는 이유는 비즈니스 때문인데, 애그리게잇이 유효한 상태인지, 아닌지를 결정하는 것은 비즈니스와 관련돼 있는 일이기 때문이다.

애그리게잇 경험 법칙

  1. 에그리게잇 경계 내에서 비즈니스 불변사항들을 보호하라.
  2. 작은 애그리게잇을 설계하라.
  3. 오직 식별자(ID)를 통해 다른 애그리게잇을 참고하라.
  4. 결과적 일관성을 사용해 다른 애그리게잇을 갱신하라.

애그리게잇을 설계할 때 깊이 새겨둬야 할 또 다른 사항은 SRP라는 단일 책임 원칙이다.

에그리게잇 모델링

애그리게잇 구현에 대한 작업을 할때, 빈약한 도메인 모델로 작업하기 쉽다.

객체지향 도메인 모델을 사용하면서, 모든 애그리게잇이 비즈니스 행위가 아닌 읽고(getters) 쓰는(setter) 공개 접근자만을 갖는 것이다. 이는 모델링을 하면서 비즈니스보다는 기술적인 부분에 초점을 맞췄을 때 발생하는 경향이 있다. 또한 비즈니스 로직이 도메인 모델을 넘어 애플리케이션 서비스까지 새어 나가지 않도록 주의해야 한다.

비즈니스 로직을 도우미(helper)나 유틸리니(util)클래스에 위임하는 것은 원하는 대로 잘 동작하지 않는다.

기초적인 애그리게잇 설계를 구현하는 방법이다.

우선 애그리게잇 루트 엔터티 클래스를 생성한다.

모든 애그리게잇 루트 엔터티는 전체 시스템에서 고유한 식별성을 가져야 한다.

추상화를 조심스럽게 선택하라

올바른 크기의 애그리게잇

  1. 작은 애그리게잇을 설계하라. 1개의 엔터티만을 갖는 애그리게잇을 생성한다.
  2. 애그리게잇 경계 내의 비즈니스 불변사항을 보호하라.
  3. 반응에 맞춘 갱신이 일어나는 시간은 얼마나 걸릴지 도메인 전문가에게 확인하자.즉시(a)또는 N초/분/시간/일과 같은 두가지 유형의 명세로 정의될 것이다.
  4. 각각의 애그리게잇들이 즉시 처리돼야 할 경우, 동일한 애그리게잇 경계 안에 그 2개의 엔터티를 구성하는 것을 긍정적으로 검토해야 한다.
  5. 각각의 애그리게잇들이 주어진 시간에 따라 각각 반응하는 경우, 결과적 일관성을 사용해 다른 애그리게잇을 갱신하라.

부연셜명 A1의 일관성 규칙 목록에는 A2가 적혀있고, C14는 소요시간(30초)를 갖는다.

결과적으로 A1과A2는 하나의 애그리게잇 A[1,2] 안으로 통합 모델링 된다.또한 런타임 중에 에그리게잇A[1,2]는 애그리게잇 C14를 갱신하도록 하는 도메인 이벤트를 발행시킨다.

모든 애그리게잇이 함께 즉각적인 갱신에 들어가야 한다고 비즈니스측에서 일방적으로 주장하지는 않는지 주의를 기울여야 한다.

단위 테스트를 위해 애그리게잇을 철저하게 캡슐화되도록 설계하자.

여기서 고려해야 하는 것은 애그리게잇이 수행하길 기대하는 대로 정확하게 수행되는지 테스트하는 것이다.


6장 도메인 이벤트와 전술적 설계

도메인 이벤트는 전략적 설계를 위해 매우 중요한 도구 이다.

그 뿐 아니라 종종 전술적 설계를 하는 동안 도메인 이벤트의 개념이 정립되면서 핵심 도메인의 일부가 된다.

전술적 설계 노력을 통해 도메인 이벤트가 도메인 모델에 구체화되고, 도메인 이벤트가 만들어지면 바운디드 컨텍스트와 다른 자원들은 이벤트를 받아 활용한다. 이는 중요한 이벤트에 관심이 있는 이벤트 리스너들에게 관련 상황의 발생을 알리는 매우 강력한 방법이다.

도메인 이벤트를 설계, 구현, 사용하기

바운디드 컨텍스트 내에 도메인 이벤트를 효과적으로 설계하고 구현하는 데 필요한 지침

도메인 이벤트 타입을 나타내는 이름은 과거에 발생한 것을 서술하는데, 이는 과거형 동사로 표현할수 있다.

도메인 이벤트는 이벤트가 만들어지는 시점에, 명령이 제공하는 모든 프로퍼티들을 담고 있어야 한다. 모든 이벤트 구독자들에게 모델 안에서 무슨 일이 벌어졌는지 온전하고 정확하게 알릴 수 있다.

💡 책에 도메인 이벤트가 포함해야 되는 프로퍼티에 대한 좋은 사례 5가지를 제시한다.

그래도 도메인 이벤트에 그 의미를 잃을 정도로 너무 많은 데이터를 가득 채우는 일이 없도록 주의해야 한다.

도메인 이벤트가 이벤트 리파지토리에 한 번 저장되면, 이벤트에 관심 있는 어떤 대상에게든지 전달될 수 있다. 이렇게 이벤트는 도메인에 주목할 만한 무언가가 발생했다는 것을 다른 모두에게 알리는 방법이다.

이벤트를 소비하는 바운디드 컨텍스트는 적절한 인과관계를 파악할 책임이 있다.

이벤트 소싱

이벤트 소싱은 애그리게인 인스턴스에 대해 변경된 것에 대한 기록으로, 발생했던 모든 도메인 이벤트를 저장하는 것을 말한다. 즉, 애그리게잇 상태 전체를 저장하는 대신, 발생했던 각 도메인 이벤트 모두를 저장한다.

이벤트 리파지토리는 모든 도메인 이벤트를 추가하는 순차적인 리파지토리 컬렉션 또는 테이블을 말한다. 이벤트 스토어는 오직 추가만 가능한데, 이런 특성으로 리파지토리 메커니즘은 매우 빠르게 동작한다.

이벤트 소싱을 사용하는 큰 이점 중 하나는 핵심 도메인에서 계속 발생하는 모든 기록을 개별적인 발생 수준으로 저장한다는 점이다. 다만 이벤트 소싱을 사용하다고 하여 꼭 CQRS를 사용할 필요는 없다.(그렇지만 CQRS와 강한 연관성을 가지고 있다.)


7장 가속화 관리 도구

이번 장에서는 매우 유용한 설계 가속화 및 프로젝트 관리 도구를 소개하고자 한다.

이벤트 스토밍

이벤트 스토밍은 빠른 주가의 합습 과정에 도메인 전문가와 개발자 모두가 참여하는 신속한 설계 기술이다. 이는 명사나 데이터보다 비즈니스와 비즈니스 프로세스에 초첨을 맞춘다.

EVENT STORMING 설명 

이벤트 스토밍은 다양한 장점이 있다.

  • 매우 구체적인 접근법이다. 모두가 설계에 기여해야할 책임을 갖는다. 모두가 보편언어를 함께 만든다.
  • 이벤트와 비즈니스 프로세스에 집중한다.
  • 매우 시각적인 접근법이다. 모두 설계 프로세스의 초반부터 참여하게 한다.
  • 가장 빠르고 가장 적은 비용으로 수행할 수 있다. 말 그대로 핵심 도메인을 수시간 내에 만들어 낼 수도 있다. 포스트잇내용이 적절하지 못하다면 버리면 그만이다.
  • 팀은 이해의 폭을 획기적으로 증진시킬 수 있다. 미팅을 통해 비즈니스에 대해 이해의 폭을 넓힐 뿐만 아니라 비즈니스 프로세스에 대한 새로운 통찰을 느낄 수 있다.
  • 모든 사람들이 무언가를 배운다. 모델의 대해 명확한 이해를 갖게 된다.
  • 모델과 모델을 이해하는 데 문제가 있다면, 이를 가능한 한 앞단계에서 빠르게 인지할 수 있다.
  • 큰 그림과 설계 수준 모델링 모두에 이벤트 스토밍을 사용할 수 있다.
  • 스토밍 세션을 하나로 제한할 필요는 없다.

모델을 만드는 데 필요한 사람, 태도, 준비물들의 목록이 있다.

  • 도메인 전문가 및 개발자와 같이 필수적인 사람들이 필요하다.
  • 많은 이벤트를 생성하겠다는 마음가짐을 가져야 한다. 평가로부터 자유로운 열린 마음을 가져야 한다.
  • 다양한 포스트잇을 많이 들어라. 포스트잇에 너무 많은 것을 적을 필요는 없다.
  • 모델링할 수 있는 넓은 벽을 확보하라.

이제 이벤트 스토밍 단계를 살펴보자.

  1. 일련의 도메인 이벤트를 포스트잇에 적으면서 비즈니스 프로세스를 도출하라.
  2. 각 도메인 이벤트를 생성하는 명령을 정의하라.
  3. 도메인 이벤트 결과를 생성해내는 명령을 엔터티/에그리게잇에 연관시키자.
  4. 모델링 공간에 경계선과 흐름을 보여주기 위한 화살표를 그리자.
  5. 사용자들이 액션을 수행하기 위해 필요한 다양한 뷰들을 식별하고, 다양한 사용자들을 위한 주요 역할들을 파악하자.

애자일 프로젝트에서의 DDD 관리

DDD를 프로젝트에 성공적으로 적용하기 위해 가장 중요한 것 중 하나는 좋은 사람들을 고용하는 것이다. 좋은 사람들을 간단히 대체할수 있는 것은 없다.

이 관점에서 보면 평균을 넘는 개발자들이 필요하다. 더 정확히 말하면, 매우 좋은 개발자가 필요하다.

SWOT 분석을 사용하자.

언제든지 프로젝트 상황을 파악하기 위해 SWOT 분석을 사용해야 한다.

출처: 위키백과

결국 모델링 부채를 가질수 있다는 사실에 충격받지 말자. 처음부터 완벽한 도메인을 기대할 수 없다.

이벤트 스토밍은 프로젝트 시작 때만이 아니라 언제든 사용할 수 있는 도구이다.

기간이 정해진 모델링

이벤트 스토밍을 통해 얻은 모든 지식을 가질 필요는 없다. 무언가 더 필요하다면 추정 시점에 추가적인 지식 획득을 위한 시간을 포함시킬수 있다.

DDD를 적용할 때 큰 어려움 중 하나는 도메인 전문가와 적절한 시간을 갖는 것이다.

도메인전문가들은 바쁘다. 그들에게 모델링 세션을 재미있고 효과적이다 라고 인식시켜줘야 한다.

배울것이 있고, 보람 있다고 인식한다면, 강한 파트너십이 만들어질 것이다.

반응형

댓글