ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • DDD 기본개념 톺아보기
    Spring Boot 2024. 4. 20. 00:23

    배경

    사내에 MSA를 도입 해보자는 이야기가 있어서,

    이왕이면 제대로 해보고 싶어 요즘 열심히 스터디 중이다.

    내가 필요하고 판단한 선수지식은 다음과 같다.

    1. 멀티모듈(https://yeoon.tistory.com/145)
    2. DDD
    3. port-adapter pattern (https://yeoon.tistory.com/148)
    4. Spring Cloud
    5. event-consistency, 카프카
    6. AWS EKS

    DDD에 관해 작성해본다.

     

    Domain Driven Design의 탄생

    • 2005년 마틴 파울러, 로드 존슨 등등등 유명한 개발 아저씨들 모여 토론.
    • 주제는 1999년 ~ 2005년 EJB 등장으로 객체지향개발 같은 방법론 적용 못하고, 코드 너무 복잡해져서 해결책 논의.
    • 에릭 에반스라는 사람 Domain Driven Design이란 방법이 해결책으로 논의하고 큰 공감을 얻음.
    • 에릭 에반스가 자신의 아이디어를 2003년 두꺼운 책으로 출판하여 설득력을 가짐.

    2003년 애릭 에반스

    • 그 아이디어란 Domain과 닮은 소프트웨어 구조를 설계하자는 아이디어.
    • 당시 구성원이 이 아이디어가 산업의 메인 스트림이 되기를 원함. 커뮤니티에서 적극적으로 발전되어 spring 커뮤니티에도 흘러들어옴
    • 2016년 스프링 컨퍼런스에서 DDD 발표 내용으로 하루종일 DDD 관련한 세션이 있었다고함 (https://blog.ordina-jworks.io/conference/2016/07/10/SpringIO16-DDD-Rest.html )
    • 매일 같이 쓰는 @Service, @Repository 또한 저 파란책에서 나온 개념이라고 한다.  

    Service 어노테이션
    Repository 어노테이션

     

    Domain이란?

    • 그래서 Domain이 무엇이냐 A domain is something of this world. 현실에 어떤 것이란다.(위 링크 DDD 발표 자료 참고)
    • 소프트웨어의 존재가치는 현실의 쓸모이다.
    • 소프트웨어는 현실의 어떤 문제를 해결하기 위해 존재한다.
    • 즉 도메인을 해결하려는 현실의 something. 비즈니스적으로 돈벌면서 해결하고 싶은 영역이라고 개인적으로는 이해함

    무엇이 DDD 공감을 얻었는가

    • 소프트웨어 설계는 예술의 영역이다. 개인의 취향을 타기 마련이며, 작성자에 따라서 천차만별로 다르며 은총알이 존재하지 않는다.
    • 도메인 주도 개발(DDD)은 현실 세계 something을 추상화해서 버릴 것은 버리고 취할 것은 취해, 엄격하게 조직화한 디자인 방식이다.
    • (은총알은 없지만 우리가 풀어나갈 도메인 관점에서는 정답에 가까운..답..? 이런 느낌 받음)
    • 당시 DDD 등장 시기 유행했던 개발 방법론의 부족했던 점이 DDD를 매력적이게 만들었다.
      • 폭포수개발 → 순서대로 진행하면서 개발 최종 산출물이 이상한 단점
      • 애자일, XP → 디자인 결정 같은 것을 최대한 뒤로 미루고 리팩토링 하다보니 결정 자체에 두려움이 생기고 결정 자체를 안 하면서 코드가 이상해지는 문제점 발견 (2001년 애자일 선언 : https://agilemanifesto.org/iso/ko/manifesto.html)
      • DDD → 도메인 기준으로 디자인 결정 진행
    • DDD를 실행하는 대상으로 개발자만 말하지 않았다. Domain을 가장 잘 아는 것은 사용자가 아니라 Domain 안에서 Player로 뛰고 있는 사람이라고함. (Ex 은행이면 돈 맡기러 오는 고객이 아니라, 은행원이 은행에 대해 가장 잘안다.)
    • Banking System을 만든다면 Banking에 대한 모든 것을 알아야 좋은 소프트웨어가 나온다.
    • 그래서 DDD를 하려면 개발자만 하는게 아니라 도메인을 가장 많은 것을 알고 있는 실무자, 운영팀, 기획자, 디자이너 등등 함께 설계 하는 것이다 라고 DDD에서 주장.

     

    유비쿼터스 언어

    • 실무자, 운영팀, 기획자, 디자이너 다같이 설계하기 위해서는 공통의 언어가 필요함
      • 도메인에 속한 구성원 모두가 사용하는 동일한 언어를 추출해서 "도메인 언어"를 만들어 소프트웨어에 반영하여 설계 디자인 해야함 이를 유비쿼터스 언어라고 표현
    • 그래서 도메인 언어 다같이 어떻게 추출하느냐
     

    Event Storming Learning - msaez

    Event Storming Learning Offline Event-Storing based MSA development Concept Event Storming is a workshop for MSA DDD that is conducted with Sticky Notes, the only tool in which all stakeholders related to the domain gather and find correlations between tas

    intro.msaez.io

     

    MSA 개발을 위한 Domain Driven Design: https://www.youtube.com/watch?v=QUMERCN3rZs

     

    • 이때 추출하는 개념들이 다음과 같으며 DDD로 만드는 소프트웨어의 기본 구성 요소임
      • Value Objects
      • Entities
      • Aggregates
      • Repositories
      • Bounded Contexts
      • Language
    • 위 기본 개념이 뭔지 코드 예시들어 설명해주는 것이 유명한 DDD 입문책

    https://product.kyobobook.co.kr/detail/S000001810495

    DDD의 기본 구성 요소 간략하게 정리

    • Value Objects
      • Avoid Stringly typed code (String으로 데이터 표현을 멈춰라)
      • Vital Building Blocks of DDD
      • 작은 불변 객체들
        • value, validation, behavior를 캡슐화
        • 기능적으로 관련 있는 것끼리 묶고
        • values가 관계 있는 것끼리 묶는다
      • 관련 있는 값을 묶으며 암시적인 것들을 명시적으로 만든다.
        • ex) Money, EmailAddress, ZIPCode, Status . . . avoid
      • 예를 들어 아래 JSON 구조를 Java로 표현하자면
        {
          "orderSeq": 1,
          "orderCreatDateTime": "2024-04-24 20:32:53",
          "orderNumber": "0000",
          "orderProductState": "미사용",
          "expiredDate": 2024-05-25
          "driver": {
            "name": "김철수",
            "tel": "010-0000-0000",
            "userLoginId": "hello",
          },
          "product": {
            "productCode": "9808908",
            "productName": "오브젝트",
            "price": 30000,
            "productState": "판매중"
          }
        }
         
        • String으로 퉁치지 말고 아래처럼 VO 객체를 정의해서 사용한다.
        • (VO 객체에게 value, validation, behavior를 캡슐화하고 메시지만 보내서 behave하게 한다. - 책 오프젝트)

    JSON 표현하는 클래스 예시

    • Entities
      • VO가 VO가 가진 attribute로 식별되는 반면에, Entities는 식별자로 구분된다.
      • Entities는 라이프사이클을 가진다. 식별자가 책임과 연관관계를 정의하기 때문이다.
      • Mutability를 가진다.
        • attribute가 동일하더라도 식별자가 다르면 다른 취급
    • Aggregates
      • Aggregates는 밀접하게 연관된 Entities의 클러스터이다. (클러스터를 Aggregate Root라 부른다.)
        • ex) Order와 OrderLineItems..
      • 하나의 Aggregates 변경은 하나의 트랜잭션 안에서 일어나야한다.
      • 다수의 Aggregates 변경은 Event Consistency에 의해 이루어진다.
    • Repositories
      • Aggregates 저장을 위한 추상 persistence store
      • DB 내부 동작은 캡슐화하고 collection 처럼 동작한다. (add, remove)
      • Criteria에 충족하는 Aggregate의 attributea만 불러오는 정교한 쿼리 기능도 지원한다.
    • Bounded Contexts
      • Domain 용어가 맥락에 따라서 다르게 해석 될 수있다.
        • 연관된 도메인을 그룹으로 묶어 구조화 한 것이 Bounded Context 이다.
        • 도메인, 모델과 언어를 분리해서 시스템간의 디커플링을 줄여, 쉽게 변경 확장이 가능하게 만든다.
      • MSA 아키텍처에서 서버를 나눌때 Bounded Contexts를 참고한다. (맹목적으로 따르지 않는다.)
      • Multiple Bounded Context를 한 트랜젝션에서 조작하는 것은 피해야한다.
    • Language
      • 도메인 언어는 Bounded Context 안에서만 의미를 가진다.

     

    Domain Events

    • 비즈니스과 관련된 과거에 발생한 이벤트
      • ex) 주문 됨, 고객 찜하기 누름 . . .
    • 이벤트 이름과 속성을 정의 하는 것이 중요
    • Bounded Context 내외부 통신이 발생하면 Event Consistency가 사용된다.
      • (Event Consistency는 내용이 많아 후에 작성 예정)
      • 간략하게 설명하면 동작의 결과(데이터)가 real time으로 저장되는게 아니라 near real time으로 관리되는 .   

    Domain 성숙도 LEVEL

    • 도메인 이벤트 사용에는 4단계 성숙도가 있다.
    1. Getter, Setter만 있는 절차적 코드
    2. Operations 추출
    3. 몇몇의 operations의 이벤트
      1. 도메인 이벤트가 State 전환에 사용
      2. 중요한 도메인 이벤트가 feed를 통해 interested parites에 노출
    4. Event Sourcing - 모든 App 상태 변화가 이벤트 변화가 이벤트 순서대로 저장된다.
      1. only event logs and snapshots are kapt (Event Store)
      2. read / write operations의 분리 (CQRS)
    반응형
Designed by Tistory.