Domain Driven Design

Domain과 Model

  • Domain은 사용자가 SW를 사용하는 대상 영역을 말한다
  • SW의 본질은 (해당 도메인에서)사용자의 문제를 해결하는 것이다
  • 그러므로 개발은 사용자 활동에 관련한 지식 체계에 집중해야 한다
  • 지식의 양이 방대하므로 Model을 통해 추상화한다

Model의 유용성

  1. 모델과 핵심 설계는 서로 영향을 주며 구체화된다
    • 유지보수와 계속되는 기능 개선을 가능케 한다
  2. 모델은 모든 구성원이 사용하는 언어의 중추이다
    • 개발자와 도메인 전문가의 의사소통시 번역이 불필요하다
    • 언어가 모델이 긴밀히 연결되므로 언어를 통해 모델을 정제할 수 있다
  3. 모델은 지식의 정수만을 뽑아낸 것이다
    • 도메인 지식을 조직화하고 가장 중요한 요소를 구분짓는다

효과적인 모델링의 요소

  1. 개발 project의 iteration 내내 모델과 구현의 연결고리를 유지한다
  2. 모델은 언어에 기반해야하고 언어 역시 모델을 토대로 정제된다
  3. 모델은 풍부한 도메인 지식을 담아야한다. 지식이 명시적으로 모델을 통해 드러나야한다
  4. 모델을 정제해가며 중요한 개념은 더하고 필요없는 개념은 제거한다

도메인의 격리

dddlayered

  • 우선 Layered Achitecture를 적용해 설계요소 별로 계층을 분리한다
  • 계층간 관계는 loosely coupled 되어야 한다
  • 모델은 도메인 계층에 존재한다. 업무 개념, 업무 상황에 관한 정보, 업무 규칙을 표현한다

도메인 객체의 생명주기 관리

  • 현재 모델링은 객체지향패러다임이 지배적이고 DDD 역시 OOP에 기반한다
  • 도메인 객체의 관리 이슈는
      1. 생명주기 동안의 무결성 유지하기
      1. 생명주기 관리의 복잡성으로 인해 난해해지는 모델 방지하기
  • 관리 패턴
      1. AGGREGATE
      • 객체간 관계로 이루어진 객체 집합에는 불변식(반드시 유지되어야하는 일관성 규칙)이 지켜져야한다
      • Entity와 ValueObject를 AGGREGATE로 모으고 각각에 대해 경계를 정의하라. 즉, 한 Entity를 AGGREGATE의 루트로 만들고 AGGREGATE 내부의 객체는 루트 엔티티를 통해서만 접근가능(캡슐화)하게 만든다
      1. FACTORY
      • 복잡한 객체이거나 AGGREGATE인 경우, 인스턴스를 생성하는 책임을 별도의 객체로 옮긴다
      • 복잡한 객체 조립 과정을 캡슐화
      • 팩토리 위치에 따라 두가지 경우로 나뉨
        • 팩토리 메소드: 서브클래스에서 클래스의 인스턴스 종류를 결정
        • 추상 팩토리: 인터페이스를 이용하여 구상 클래스를 지정 않고도 생성
      1. REPOSITORY
      • db와 같은 인프라스트럭쳐에 접근하는 행위를 캡슐화
      • 더불어 인프라스트럭쳐에 의존하지 않고 순수한 객체로 핸들링하는 수단
      • 인프라의 객체로 구성된 컬렉션 객체를 메모리에 올린다는 느낌
      • 즉, REPOSITORY 통해 클라이언트는 영속화된 객체를 획득하고, 해당 객체의 생명주기를 쉽게 관리한다
      • 또한 데이터 소스로부터 도메인 설계를 분리한다
      • The ORM is always an implementation detail of the repository.

DDD의 적용

BC(Bounded Context) + MS(Microservice)

  • 단일 시스템(기능 측면) 성장은 이슈를 내포

    • 통합 db위의 단일 코드가 확장되는 형태
    • 도메인 부재의 문제
      • 프레젠테이션, 서비스, data, db 등의 레이어로 구분된 수평 level의 계층만 존재
      • 수직적으로 묶여진 BC없이(도메인 구분 없이) 분별없이 확장됨
  • BC의 적용

    • 패키지를 나누어 응집도를 높이고 문제를 완화(ex. user, project)

    • Screen Shot 2019-07-22 at 12 23 39 AM

      • 여전히 모호한 경계
      • Q: User와 Project는 N:N 아닌가?
    • Screen Shot 2019-07-22 at 12 26 14 AM

      • A: BC를 잘 나누었으면 사실 user와 project는 별개임이 드러남
      • 부가적으로 클래스간 통신을 위한 인터페이스가 도출됨
  • MS의 적용 -> 언어의 경계를 찾아 BC를 구성하는데 도움

    • 서비스 관점에서의 컴포넌트화

      • 독립배포 -> 서비스의 응집도 높아짐
      • 명시적이고 공개된 인터페이스
    • 비즈니스 수행에 따른 구성

      • 조직의 형태에 따라 시스템을 설계(ex. 기능조직, 목적조직)
    • 분산화된 데이터 관리

      • 통합 db에서라면 join의 의지가 자꾸드러난다. 즉, 다른 ms를 호출하는게 아니라 (편하게) join을 하게되는 문제
    • 진화하는 설계

      • 서비스별 독립적인 변경이 가능

refs