인생은 고통의 연속

도메인 주도 설계(DDD-Domain Driven Design) - 도메인 모델 본문

아키텍쳐/도메인 주도 설계

도메인 주도 설계(DDD-Domain Driven Design) - 도메인 모델

gnidoc 2019. 3. 19. 18:50
    반응형

    기존의 설계 방식

    컨트롤러-서비스-DAO-DTO 

    (전형적인 Spring API 구조)

     

    도메인

    도메인 : 문제 해결하고자 하는 문제 영역. 도메인은 여러 하위 도메인으로 구성한다.

    SW는 도메인의 모든 기능을 제공하지 않는다.(예를 들어 결제는 외부 시스템(PG)을 사용하는 것처럼)

     

    도메인 모델

    도메인 모델 : 특정 도메인을 개념적으로 표현. 도메인 자체를 이해하기 위한 개념 모델.

    기능과 데이터를 함께 보여주는 객체 모델은 도메인을 모델링하기 적합함. 하지만 도메인 모델은 객체로만 모델링하지 않는다. 즉, 클래스/상태 다이어그램과 같은 UML(Unified Modeling Language) 표기법만 사용해야 하는건 아님. 관계가 중요한 도메인이라면 그래프를 이용해서 도메인을 모델링. 계산 규칙이 중요하다면 수학 공식을 활용해서 도메인 모델. 도메인을 이해하는데 도움이 된다면 표현 방식은 중요하지 않다.

    도메인 모델은 개념 모델을 이용해서 바로 코드를 작성하지 않는다. 구현 기술에 맞는 구현 모델 필요. 개념모델이 구현모델과 같지 않지만 구현모델이 개념 모델을 최대한 따르도록 할 수 있다.

    • 객체 기반 모델을 이용해서 도메인 표현 = 객체 지향 언어를 사용하여 개념 모델 구현
    • 수학적인 모델을 사용 = 함수를 이용해서 도메인 모델 구현

    하위 도메인이 다루는 영역은 서로 다르기 때문에 같은 용어라도 하위 도메인 마다 의미가 달라짐

    모델의 각 구성요소는 특정 도메인을 한정할 때 비로소 의미가 완전해지기 때문에 하위 도메인마다 별도로 모델을 만들어야한다.

    개념 모델 : 순수하게 문제를 분석한 결과물. DB, 트랜젝션, 성능을 고려X. 따라서 개념 모델은 구현 가능한 형태의 모델로 전환하는 과정을 거침. 완벽한 도메인을 표현하는 모델을 만드는 것은 불가능하므로 전반적인 개요를 알 수 있는 수준으로 개념 모델을 작성

     

    도메인 모델 패턴

    도메인 모델은 결국 아키텍처상의 도메인 계층을 객체 지향 기법으로 구현하는 패턴

    도메인 계층은 도메인의 핵심 규칙을 구현. 예를 들어 주문 도메인의 경우 '출고 전에 배송지를 변경할 수 있다'는 규칙을 구현한 코드가 도메인 계층에 위치함. 이런 도메인 규칙을 객체 지향 기법으로 구현하는 패턴이 도메인 모델 패턴

     

    도메인 모델 도출

    도메인 모델링 기본 작업 : 모델을 구성하는 핵심 구성요소, 규칙, 기능을 찾는 것(요구사항에서 출발)

    요구사항에서 메서드, 데이터 등을 정의하고 찾아내는 것.

     

    엔티티와 밸류(Entity & Value)

    모델은 크게 엔티티와 밸류로 구분

     

    엔티티

    엔티티란 서로 구별되는 하나하나의 대상. 주로 개체를 의미함.

    엔티티는 객체마다 고유한 다른 식별자를 갖는다.

     

    엔티티의 식별자 생성

    식별자는 다음 중 한가지 방식으로 생성

    • 특정 규칙에 따라 생성 - 주문번호, 카드번호
    • UUID 사용 - 개발 언어에서 지원하는 UUID 생성기 사용
    • 값을 직접 입력 - 회원 아이디, 이메일
    • 일련번호 사용 - 시퀀스나 DB의 자동 증가 칼럼 사용(auto increment)

     

    밸류타입

    밸류타입은 코드의 의미를 더 잘 이해할 수 있도록한다.

    • 받는 사람 이름(String), 받는 사람 폰번호(String) → 받는 사람(Receiver Class)
      (Receiver Class는 받는 사람이라는 도메인 개념을 표현)
    • 주소1(String), 주소2(String), 우편번호(String) → 주소(Address Class)
      (Address Class는 주소라는 도메인 개념을 표현)

     

    엔티티 식별자와 밸류 타입

    대부분 엔티티 식별자의 실제 데이터는 String과 같은 문자열로 구성됨.

    Money(Class)가 단순 숫자가 아닌 도메인의 '돈'을 의미. 식별자는 단순 문자열이 아니라 도메인에서 특별한 의미를 지니는 경우가 많음. 식별자를 위한 밸류타입을 사용해서 의미가 잘 드러나도록 할 수 있다.

    주문(Order)의 식별자 타입으로 String 대신 OrderNo 밸류 타입을 사용하면 타입을 통해서 주문 번호라는 것을 나타낼 수 있음.

     

    도메인 모델에 set 메서드 넣지 않기

    get/set 메서드는 습관적으로 추가하는 메서드. set 메서드를 구현해야할 특별한 이유가 없다면 불변 타입의 장점을 살릴 수 있도록 밸류 타입은 불변으로 구현

    set 메서드의 2가지 문제

    • 도메인의 핵심 개념이나 의도를 코드에서 사라지게 한다.

    changeShippingInfo() → setShippingInfo()
    배송지 정보를 새로 변경한다 → 단순 배송지 값을 설정

    • 도메인 객체를 생성할 때 완전한 상태가 아닐 수 있다.

    생성자를 통한 초기화가 아닌 set 메서드를 통해 초기화할 경우 값이나 검사 코드가 누락될 수 있다.
    도메인 객체가 불완전한 상태로 사용되는 것을 막으려면 생성 시점에 필요한 것을 전달해 주어야 한다.

     

    도메인 용어

    도메인에서 사용하는 용어는 매우 중요하다. 도메인에서 사용하는 용어를 최대한 코드에 반영하면 코드를 도메인 용어로 해석하거나 도메인 용어를 코드로 해석하는 과정이 줄어든다.

    STEP1, STEP2, STEP3... 대신에 PAYMENT_WAITING, PREPARING, SHIPPED... 사용

    코드의 가독성을 높여서 코드를 분석하고 이해하는 시간을 절약. 도메인 용어를 사용해서 최대한 도메인 규칙을 코드로 작성하게 되므로 의미를 변환하는 과정에서 발생하는 버그도 감소.

    도메인에 어울리지 않는 단어를 사용하면 코드는 도메인과 점점 멀어짐. 도메인 용어에 알맞은 단어를 찾는 시간을 아까워하지말자

    반응형

    '아키텍쳐 > 도메인 주도 설계' 카테고리의 다른 글

    도메인 주도 설계 - 아키텍처  (2) 2019.03.23
    Comments