jc.jang

도메인 주도 설계 구현 - 1장 본문

개발/도메인 주도 설계 구현

도메인 주도 설계 구현 - 1장

jangstory 2020. 1. 6. 22:38

이 책을 시작하기 위한 가이드

  • 에릭 에반스는 도메인 주도 설계에서 패턴 언어의 필수적인 부분이 무엇인지를 보여줬다. 패턴 언어란 서로가 얽혀 있는 몇가지 소프트웨어 패턴의 집합이다.

  • 이 책을 읽어갈 때 이전까지 접하지 못했던 DDD 패턴을 마주칠 수 있다.

  • 만약 상대적으로 DDD를 생소하게 느낀다면, 이어지는 절의 내용은 여러 패턴이 서로 맞물리는 방식과 빠르게 이 책에 적응하는 방법을 이해하는 데 큰 도움이 될 것이다.

DDD의 큰 그림

  • 이 책의 도입부에선 DDD의 주춧돌 중 하나인 유비쿼터스 언어를 다룬다.
  • 유비쿼터스 언어는 단일 바운디드 컨텍스트의 경계 안쪽에서 적용하게 된다.

전략적 모델링

  • 바운디드 컨텍스트는 도메인 모델을 적용할 수 있는 개념적 경계다.

  • 이는 팀에서 이야기를 위해 사용하며 신중히 설계된 소프트웨어 모델 안에서 표현되는 유비쿼터스 언어를 위한 컨텍스트를 제공한다.

아키텍처

  • 바운디드 컨텍스트를 다루는 강력한 아키텍처 스타일로는 헥사고날(서비스 지향, REST, 이벤트 주도 등의 여러 스타일을 다루는 데 사용할 수 있는)이 있다.

전술적 모델링

  • 우리는 DDD의 기반을 이루는 패턴을 사용해 전술적 측면에서 바운디드 컨텍스트 내부를 모델링한다.

  • 전술적 설계 중 가장 중요한 패턴은 애그리게잇이다.

  • 하나의 애그리게잇은 하나의 엔터디나 여러 엔터티와 값 객체의 클러스터로 구성될 수 있으며, 애그리게잇의 수명이 다할 때까지 트랜잭션적 일관성이 유지돼야만 한다.

  • 애그리게잇을 효과적으로 모델링하는 방법을 이해하는 일은 상당히 중요하며, 이는 DDD의 기반을 이루는 요소 중 가장 이해도가 낮은 기법이기도 하다.

  • 애그리게잇의 인스턴스는 리파지토리를 사용해 저장되며, 이후에는 리파지토리로부터 검색해 가져올 수 있다.

  • 도메인 모델의 내부에서 무상태 서비스를 사용해 엔터티나 값 객체에는 잘 맞지 않는 비즈니스 오퍼레이션을 수행할 수 있다.

  • 도메인 이벤트를 사용해 도메인에서 발생하는 중요한 사건을 나타낼 수 있다.

  • 모듈의 올바른 설계는 굉장히 중요하다.

1장 DDD를 시작하며

설계는 단순히 어떻게 보이고 느껴지는가에 관한 것이 아니다. 설계는 어떻게 동작하는가에 관한 것이다.
-스티브 잡스-

  • DDD를 사용할 때 얻을 수 있는 이익과 DDD를 달성하는 방법을 소개한다. 실제 현실에서 겪게 되는 DDD의 도전을 마주하고 있는 가상의 회사와 팀에 관한 케이스 스터디도 함께 다룬다.

  • 버그가 없는 소프트웨어를 만든다 해도 그것이 양질의 소프트웨어를 설계했다는 것을 의미하지는 않는다.

  • DDD는 우리가 높은 품질의 소프트웨어 모델을 설계할 수 있도록 해준다.

나도 DDD를 할 수 있을까

다음과 같은 조건을 갖췄다면 DDD를 구현할 수 있다.

  • 매일 훌륭한 소프트웨어를 만들려는 열정과 목표를 이루려는 끈기
  • 배우고 개선하고자 하는 열망과 당신에게 그것이 필요하다고 인정할 수 있는 배짱
  • 소프트웨어 패턴을 이해하고 적절하게 적용할 수 있는 적성
  • 증명된 애자일 방법론을 사용해 설계 대안을 탐구해볼 기술과 인내력
  • 현상에 도전해볼 용기
  • 세부사항에 관심을 갖는, 실험해보고 발견하려는 의지와 능력
  • 더 현명하고 좋은 코드를 작성하는 법을 찾아내려는 추진력
  • 학습 곡선(learning curve)이 없을 것이라 말하진 않겠다. 매우 가파른 학습 곡선을 겪을 것이다. 하지만 이 책은 그 곡선을 가능한 한 완만하게 만들 수 있도록 돕고자 쓰였다.

  • DDD는 다른 무엇보다도 기술에 관한 것이다. DDD의 가장 중심에 있는 원리는 토의, 경청, 이해, 발견 그리고 비즈니스의 가치, 모든 지식을 중앙화하는 모든 것이다.

  • DDD를 하기 위해 오랜 경력의 소프트웨어 개발 경험이 필요할 수도 있다. 하지만 그 경험이 비즈니스에서 가장 중요한 분야를 가장 잘 알고 있는 도메인 전문가로부터 듣고 배우는 능력을 가르쳐주진 않는다.

  • 도메인 전문가 역시 개발자의 말을 경청해야한다.

  • 당신이 어떤 사람이든 간에 중요한 사실이 있다. DDD로 성공하기 위해 당신은 무언가를, 아니 아주 많은 무언가를 배우게 된다. 당신은 똑똑하고, 그래서 항상 배워야한다. 그러나 우리 모두는 이런 문제를 만난다.

개인적으로 나는 항상 배울 준비가 돼 있지만, 항상 가르침 받기를 좋아하진 않는다.
-윈스턴 처칠 경-

  • 그래서 이 책이 필요하다. 이제 내가 왜 DDD를 해야 하지?에 대해 답한다.

내가 왜 DDD를 해야 할까

  • 도메인 전문가와 개발자들의 눈높이를 맞춰줌으로써, 코더에게뿐 아니라 비즈니스 관계자에도 말이 되는 소프트웨어를 만들게 한다.
  • 지식의 중앙화가 핵심이다.
  • 도메인 전문가와 소프트웨어 개발자 그리고 소프트웨어 사이에 전혀 변역이 필요하지 않다.
  • 설계는 코드이며, 코드가 설계다. 설계는 어떻게 작동하는가다. 애자일 발견 프로세스를 사용한 빠른 경험적 모델을 통해 최고의 코드 설계가 무엇인지 알 수 있다.

비즈니스 가치를 제공하는 것은 어려울 수 있다.

  • 일반적인 비즈니스 소프트웨어의 개발은 진정한 비즈니스 가치를 제공하는 소프트웨어의 개발과는 분명히 다르다.

  • 비즈니스의 지식은 절대 중앙화되지 않는다.

  • 도메인 전문가와 소프트웨어 개발자 간의 이견은 비즈니스 소프트웨어 개발 노력에서 만나는 최악의 단절 중 하나다.

  • 일반적으로, 진정한 도메인 전문가는 비즈니스 가치를 제공하는 데 집중한다. 한편, 소프트웨어 개발자는 전형적으로 기술과 비즈니스 문제점의 기술적 해결에 더 관심을 갖는다.
  • 이와 관련된 또 하나의 문제점은 한 명 또는 그 이상의 도메인 전문가 사이에 의견이 일치하지 않는 부분이다.

DDD가 해줄 수 있는 일

  1. DDD는 도메인 전문가와 소프트웨어 개발자가 비즈니스 전문가의 심적 모델을 반영한 소프트웨어를 함께 개발할 수 있게 해준다.

    이런 측면에서 도메인 전문가와 소프트웨어 개발자는 모델을 만들려는 비즈니스 영역의 유비쿼터스 언어를 개발하는 데 함께 전념한다.
    절대로 우리와 그들을 나누지 않는다. 항상 우리여야한다.

  2. DDD는 비즈니스의 전략적 이니셔티브를 다룬다.

  3. DDD는 실행 가능한 소프트웨어 상품을 분석하고 개발하는 전술적 설계 모델링 도구를 사용해 실제 소프트웨어의 기술적 요구에 응한다.

도메인의 복잡성과 씨름하기

  • 우선은 DDD를 비즈니스에서 가장 중요한 영역에서부터 사용해 나가야 한다.

  • 핵심 도메인과 그 다음으로 중요한 지원 서브도메인은 가장 큰 투자가 필요한 부분이다.

  • 그런 뒤에야 우리는 복잡성의 의미에 대해 논의할 수 있다.

  • 복잡성을 정의하기에 앞서, 중대한 것이 무엇인지 먼저 정하는 편이 더 쉬울지도 모른다.

무기력증과 기억 상실

  • 무기력증(애너믹)은 위험한 부작용을 동반한 심각한 질환이 될 수 있다.

  • 애너믹 도메인 모델이란 이름이 처음 지어졌을 땐, 고유한 행동 특성의 힘이 담기지 않은 약한 도메인 모델이 좋은 것일 수 없듯이 긍정적인 의미의 용어가 아니었다.

  • 당신이 도메인 모델을 개발하며 높은 비용을 지불하지만 얻는 것은 거의 없거나 전혀 없기 때문에 애너믹 도메인 모델은 나쁘다.

왜 무기력증이 일어나는가

  • 종종 개념이나 API 기능을 설명하기 위해 좋은 설계 원칙에 관한 고민 없이 가능한 한 가장 단순한 방법으로 샘플 코드를 나타내는 데 집중하곤 한다.

  • 과도하게 단순화된 샘플 코드에는 많은 수의 게터와 세터가 나타나기 마련인데, 이런 코드가 설계를 다시 살펴보지 않은 상태로 매일같이 단순히 그대로 복사해 사용되고 있다.

  • 마이크로소프트 비주얼 베이직의 오래된 역사는 오늘날 우리에게 많은 영향을 미쳤다.

  • 이들은 처음부터 비주얼 베이직 양식 설계자에게 인기가 많았던 속성 게터와 세터로부터 도움을 받았었다.

  • 자바빈 표준은 자바의 비주얼 프로그래밍 도구를 만드는 데 도움을 주기 위해 만들어졌다.

  • 마이크로소프트 액티브엑스를 자바 플랫폼으로 가져오는 것이 동기였다.

  • 거의 모든 프레임워크와 라이브러리는 자바빈에 편승했다.

  • 이는 자바 SDK/JDK의 상당 부분을 비롯해, 하이버네이트(자바 기반의 ORM)와 같은 유명 라이브러리까지 포함했다.

  • DDD의 입장에서 보자면, 하이버네이트는 도메인 모델을 저장하기 위해 만들어졌다. 이는 .NET 플랫폼의 등장으로 계속됐다.

  • 흥미롭게도, 하이버네이트를 사용해 영속된 초기 단계의 어떤 도메인 모델도 모든 도메인 객체의 모든 영속성 단순 속성과 복잡한 연관성을 위한 게터 및 세터를 노출해야 했다.

  • 이는 풍부한 행동 인터페이스를 가진 POJO(Plain Old Java Object)를 설계할 때도, 내부를 공개적으로 노출시켜 하이버네이트가 당신의 도메인 객체를 저장하고 재구축할 수 있도록 해야 했다는 의미다.

  • 물론 퍼블릭 자바빈 인터페이스를 숨기기 위한 여러 방법이 있었지만, 대부분의 개발자는 그러려고 하지 않았거나 왜 그렇게 해야 하는지 이해조차 하지 못했다.

  • 오늘날 시장의 거의 모든 프레임워크는 단순한 객체에 퍼블릭 속성을 사용하길 요구하는 동시에 권장하고 있다.

  • 대부분의 개발자가 엔터프라이즈 전반에 걸쳐 있는 모든 애너믹 클래스에 영향을 받을 수밖에 없다.

  • 이 사실을 받아들이자. 당신도 이를 피해갈 수 없지 않았는가? 결과적으로, 우리는 온통 무기력증에 빠지게 됐다.

무기력증이 당신의 모델에 한 일을 보라

  • 온통 무기력증이 기억력 상실과는 무슨 상관인가? 애너믹 도메인 모델의 클라이언트 코드를 읽을 때, 무엇을 주로 보는가?

  • 예제 코드를 바꾸려고 할 때 세가지 문제점

  1. saveCustomer() 인터페이스를 통해 알 수 있는 의도가 거의 없다.
  2. saveCustomer()의 구현 그 자체가 숨겨진 복잡도를 높인다.
  3. 도메인 객체 Customer는 사실 전혀 객체가 아니다. 이는 단지 단순한 데이터 홀더일 뿐이다.
  • 이 골치 아픈 상황을 무기력증으로 인한 기억력 상실(anemia-induced memory loss)증상이라고 부르자.

  • 이 암묵적이고 완전히 주관적인 코드 설계를 만들어내는 일은 프로젝트에서 내내 일어난다.

DDD는 어떻게 하는가

  • 구현에 관한 주제에서 벗어나 유비쿼터스 언어에 관해 얘기해보자.

  • 유비쿼터스 언어와 바운디드 컨텍스트는 DDD의 강점을 받치는 두 기둥을 이루며, 이 두 기둥은 어느 한쪽 없이는 온전히 설 수 없다.

컨텍스트에 맞는 용어

일단 지금은 바운디드 컨텍스트를 전체 애플리케이션이나 유한 시스템의 개념적 경계로 생각하라. 이 경계가 존재하는 이유는 그 경계 안의 해당 도메인 용어, 구, 문장, 즉 유비쿼터스 언어가 특정 컨텍스트의 의미를 띠고 있음을 강조하기 위해서다. 이를 벗어나 해당 용어를 사용할 땐 아마 다른 의미를 띠고 있을 가능성이 생기며, 아마도 거의 대다수가 그런 경우일 것이다. 2장에선 이 바운디드 컨텍스트를 깊이 있게 다룰 것이다.

유비쿼터스 언어

  • 유비쿼터스 언어는 팀 내에 공유된 언어다. 도메인 전문가와 개발자 간에 같이 공유된다.

  • 그리고 실제론 해당 프로젝트에 참여하는 모든 사람 간에 공유된다.

  • 개발자들에게 사용하도록 강요되는 많은 비즈니스 용어가 아니며 팀 전체에 의해 만들어진 실제 언어다. 언어는 시간이 지남에 따라 성장한다.

그래서 유비쿼터스 언어가 뭔지 알겠다고?
도메인 전문가와 소프트웨어 개발자 모두에 의해 개발되어 공유된 언어다.

  • 전문가의 생각 속에 존재하는 언어와 언어가 진화해나가는 방향 사이에 흥정이나 논쟁이 발생할 수 있다.

  • 이 모든 과정은 오랫동안 중요하게 쓰일 최고의 언어를 만들어가는 자연스러운 과정의 일부다.

  • 유비쿼터스 언어를 정확히 담아내는 방법

  1. 물리적이고 개념적인 도메인 그림을 그리고 이름과 행동을 붙여보라.
  2. 간단한 정의로 구성된 용어집을 만들라.
  3. 용어집이 마음에 들지 않는다면, 형식에 얽매이지 말고 소프트웨어의 중요한 개념을 담은 그림을 넣어서 문서의 형태로 남기자. 여기서의 목표는 추가적인 용어와 구문을 언어로 끄집어내는 데 있다.
  4. 만들어진 구문을 나머지 팀원들과 돌려보며 리뷰하자.
  • 이런 방법은 유비쿼터스 언어를 만드는 이상적인 몇가지 첫 단계다.

  • 처음엔 도메인에 딱 맞는 유용한 유비쿼터스 언어를 만드는 길을 갈 수 있도록 우리를 이끌고 영감을 주었던 결과물은 시간이 지나면서 점차 쓸모없어질 가능성이 매우 크다.

  • 유비쿼터스 언어와 소스 코드가 빠르게 발전함에 맞춰 유지하기가 어렵다면, 언제든 그림과 용어집과 그 밖의 다른 문서를 버릴 준비를 하라.

유비쿼터스지만 보편적이지는 않다

  • 유비쿼터스 언어의 기초적인 개념들 몇가지
  1. 유비쿼터스는 '만연하다.' 혹은 '어디서나 발견된다.'는 의미, 즉 팀원 간에 사용되고 팀이 개발하는 하나의 도메인 모델로 발현된다는 의미이다.
  2. 유비쿼터스라는 단어의 사용은 엔터프라이즈 전체의 전사적인, 혹은 세계적이고 보편적인 도메인 언어를 설명하려는 의도는 아니다.
  3. 바운디드 컨텍스트당 하나의 유비쿼터스 언어가 있다.
  4. 바운디드 컨텍스트는 우리가 처음 상상했던 것보다 상대적으로 더 작다. 바운디드 컨텍스트는 격리된 비즈니스 도메인의 완전한 유비쿼터스 언어를 포착할 만큼만 크다.
  5. 유비쿼터스 언어는 바운디드 컨텍스트를 격리시키고 그 안에서 프로젝트의 개발 업무를 수행하는 팀 내부에서만 유비쿼터스하다.
  6. 하나의 바운디드 컨텍스트를 개발하는 하나의 프로젝트에는 항상 하나 이상의 격리된 바운디드 컨텍스트가 있으며, 이는 컨텍스트 맵을 사용해 통합된다. 일부 용어가 겹칠지라도, 통합되는 바운디드 컨텍스트 각각은 자신만의 유비쿼터스 언어를 갖고 있다
  7. 당신이 전체 엔터프라이즈에 혹은 그보다 넓은 단위에 단일 유비쿼터스 언어를 적용하려 한다면 실패할 것이다.

DDD를 사용하는 데서 오는 비즈니스 가치

  • 어떤 기술이나 기법을 사용할 때의 가장 훌륭한 정당화는 비즈니스에 가치를 제공하는 경우라고 생각한다.

  • DDD를 사용하는 데서 오는 덜 기술적인 이점들도 있다.

  1. 조직이 그 도메인에 유용한 모델을 얻는다.
  2. 정교하고 정확하게 비즈니스를 정의하고 이해한다.
  3. 도메인 전문가가 소프트웨어 설계에 기여한다.
  4. 사용자 경험이 개선된다.
  5. 순수한 모델 주변에 명확한 경계가 생긴다.
  6. 엔터프라이즈 아키텍처의 구성이 좋아진다.
  7. 애자일하고, 반복적이고, 지속적인 모델링이 사용된다.
  8. 전략적인 동시에 전술적인 새로운 도구가 적용된다.

1. 조직이 그 도메인에 유용한 모델을 얻는다.

  • DDD의 초점은 비즈니스적으로 중요한 곳에 우리의 노력을 투자한다는 점이다. 핵심 도메인에 초점을 맞춘다.

2. 정교하고 정확하게 비즈니스를 정의하고 이해한다.

  • 시간이 지남에 따라 이 모델이 점차 정제되면서, 비즈니스적으로 깊이 있는 이해를 형성해가고 이를 분석 도구로 활용할 수 있게 된다.

  • 서로간에 반론을 펴고 기술팀 파트너에 영향받으면서, 도메인 전문가의 머리로부터 상세한 내용이 표면화된다.

3. 도메인 전문가가 소프트웨어 설계에 기여한다.

  • 개발자는 도메인 전문가와 하나된 팀으로 공통의 언어를 공유한다.

  • 그들은 함께 일하는 도메인 전문가로부터 지식을 전달받는 이점을 얻는다.

4. 사용자 경험이 개선된다.

  • 사용자 경험이 근가을 이루는 전문가 모델의 윤곽을 따라 설계돼야, 사용자가 올바른 결론을 내리도록 이끌 수 있다.

  • 실제로 소프트웨어 자체만으로 사용자를 교육하게 되며, 이는 비즈니스의 간접비용을 줄여준다.

비즈니스적 측면에서 기술적인 이득을 살펴보자.

5. 순수한 모델 주변에 명확한 경계가 생긴다.

  • 기술 팀은 비즈니스에 이득이 되는 방향으로 지향점을 맞춰감으로써, 프로그래밍과 알고리즘적 문제에 더 많은 관심을 드러내지 않도록 권장된다.

6. 엔터프라이즈 아키텍처의 구성이 좋아진다.

  • 바운디드 컨텍스트를 잘 이해하고 신중하게 분할한 경우, 엔터프라이즈 내의 모든 팀은 어디서 왜 통합이 필요한지 분명하게 이해하게 된다.

7. 애자일하고, 반복적이고, 지속적인 모델링이 사용된다.

  • DDD는 도메인 전문가의 심적 모델을 신중히 정제해서 비즈니스에 유용한 모델로 만드는 방법에 관한 문제다.

  • 팀의 노력은 애자일 접근법을 따라 투입되는데, 이는 반복적이고 점진적인 것이다.

8. 전략적인 동시에 전술적인 새로운 도구가 적용된다.

  • 주어진 바운디드 컨텍스트를 각각 담당하기도 하는 서로 다른 팀은 컨텍스트 맵을 사용해 바운디드 컨텍스트를 전략적으로 분리하고 그들 사이의 통합을 합의한다.

  • 팀은 하나의 모델링 경계 안에서 유용한 전술 모델링 도구를 얼마든지 이용할 수 있다. 애그리게잇, 엔터티, 값 객체, 서비스, 도메인 이벤트 등이 있다.

DDD 적용의 난관

  • 일반적인 문제점
  1. 유비쿼터스 언어를 만드는 데 드는 시간과 노력을 계산 하는 것
  2. 도메인 전문가를 시작부터 참여시키고 프로젝트 내내 함께하는 것
  3. 도메인 내의 해결책에 관한 개발자의 사고방식을 바꾸는 것
  • 도메인 전문가에게 필요한 도움을 요청하는 일 역시 어려울 수 있다. 하지만 반드시 그렇게 해야 도메인의 깊은 지식을 알아낼 수 있다.

  • 그들이 이야기하는 언어를 소프트웨어로 녹여냄으로써 도메인에 대한 전문가의 심적 모델을 반영해야 한다.

  • 작업하고 있는 도메인이 진정으로 비즈니스에 차별성을 부여한다면 도메인 전문가의 최전선의 중요한 지식이 담겨 있을 것이고, 이를 끌어내야 한다.

  • 개발자는 기술적인 해결책이 편하지만, 덜 기술적으로 생각하는 편이 더 나은 경우가 있다.

애자일 예제에서 설명하지 않은 용어 설명

  • 스크럼: 프로젝트 관리를 위한 상호, 점진적 개발 방법론이며 애자일 소프트웨어 공학 중의 하나이다. 개발 주기는 30일 정도로 조절하고 개발 주기마다 실제 동작할 수 있는 결과를 제공한다. 개발 주기마다 적용할 기능이나 개선에 대한 목록을 제공한다. 날마다 15분 정도 회의를 가진다.
  • 제품 백로그: 제품에 필요한 모든 항목을 순서를 매긴 목록이다. 제품 백로그는 제품과 사용 환경이 발전함에 따라 발전한다.
  • 스프린트: 2~4주 정도의 짧은 기간으로, 반복적인 개발 주기를 뜻한다.
Comments