Post
EN

도메인 주도 설계 및 구현 (3)

값 객체 (Value Object)

-> 값 객체는 DDD의 필수적인 구성 요소 이다.

​

*값 이점에 대해 알라

측정하고 수량화하거나 설명해주는 값 타입은 생성, 테스트, 사용, 최적화, 유지관리가 더 쉽다.

​

모델 요소의 특성에만 신경을 쓰고 있다면, 이를 값 객체로 분리하라.

값 객체가 담을 특성의 의미를 표현하고, 그에 관한 기능도 부여하자.

값 객체를 변경이 불가능한 것으로 취급하자.

식별자는 부여하지 말고, 엔티티를 유지할 때 필요한 설계 복잡성을 피하도록 하자.

​

값의 특징

​

  • 도메인 내의 어떤 대상을 측정하고, 수량화하고, 설명한다.

  • 불변성이 유지될 수 있다.

  • 관련 특성을 모은 필수 단위로 개념적 전체를 모델링한다.

  • 측정이나 설명이 변경 될 땐 완벽히 대체 가능하다.

  • 다른 값과 등가성(value equlity)을 사용해 비교할 수 있다.

  • 협력자(collaborator)에게 부작용이 없는 행동 (side effect free behavior)을 제공한다.

​

(와트 커닝 햄 전체 값(whole value) 패턴)

​

– 사설 –

  • 요즘은 DDD 관련해서 잘 정리되지 않은 체 상상한 대로 하다보니 조금 패키지 나누는 것 부터 문제가 발생되곤 한다.

  • 값 객체인 경우 예로는 상품 정보중 가격 정보에 해당되는 것을 값 객체로 빼고, 내부적으로 들어오는 값에 대해 처리하는 로직으로 작성했었다. 불변형 객체를 맞춰서 작성하였다.

  • 그 밖의 각 계층별 나누는 것은 아직 익숙하지 않은데, 어디 참고할 만한 코드를 봤으면 좋겠다.

​

함수형의 길

함수형 프로그래밍 언어는 일반적으로 이런 특성을 강화 시킨다.

사실 순수한 함수형 언어는 오직 부작용 없는 행동만 하며, 모든 클로저는 오직 불변성 값 객체만 받아들이거나 들어내도록 요구한다.

​

일관된 바운디드 컨텍스트 내에 유비쿼터스 언어를 모델링 하는 문제이다.

​

서비스

​

도메인 고유의 바운디드 컨텍스트 내에 유비쿼터스 언어를 모델링 하는 문제이다.

​

도메인 모델은 일반적으로 비즈니스의 특징 측면에 집중된 소단위 행동을 처리 하기 때문에,

도메인 서비스는 도메인 모델과 비슷한 원칙을 고수하는 경향이 있다.

​

도메인 서비스는 다음과 같은 경우에 사용할 수 있다.

  • 중요한 비즈니스 프로세스를 수행할 때

  • 어떤 컴포지션에서 다른 컴포지션으로 도메인 객체를 변형 할 때

  • 하나 이상의 도메인 객체에서 필요한 입력값을 계산 할 때

​

특정 범주 안에 들어가는 것을 바운디드 컨텍스트로 분리하고, 정적 메서드 형태로 불러와서 사용할 수 있도록 한다. 이때 서비스는 무상태이다.

​

책에선 예제에 레지스트리 객체가 있었는데, 도메인과 구현 세부사항 사이의 결합을 분리해준다. 하지만 선호하는 방식은 아니라고 한다.

​

  • 도메인 서비스를 과용하면 안티 패턴인 애너믹 모델로 이어질 수 있다.

  • 서비스를 구현하는 구체적인 실행 단계

  • 분리된 인터페이스를 사용하는 장, 단점

​

도메인 이벤트

도메인에서 발생한 사건을 포착하기 위해 도메인 이벤트를 사용하자.

​

도메인 이벤트를 나타낼 수 있는 경우는 아래와 같다.

  • ~할 때

  • 그런일이 일어나면

  • ~하면 저에게 알려주세요. ~와 하면 저에게 통보해주세요.

  • ~한 일의 발생

​

애그리게잇으로 이벤트를 발행할 땐 이벤트의 이름에 과거 시점을 반영하는 것이 좋다.

  • 이벤트가 언제 일어 났는지 나타내는 timestamp가 필요하다.

(현재 나는 위 사항을 중요하게 처리하지 않고 있었다.)

​

Event에 해당되는 모델에 위의 timestamp를 설정할 수 있는 인터페이스를 만들자.

​

이벤트 저장소 내용은 있었지만 간략했다.

​

멱등한 오퍼레이션

멱등한 오퍼레이션 (Idempotent operation)은 같은 오퍼레이션이 두 번 이상 수행되어도, 한번만 수행 했을 때와 같은 결과에 이르는 동작을 한다.

​

모듈

시스템에 관한 이야기를 알려주고 응집력 있는 개념의 집합을 담을 수 있도록 모듈을 선택하자.

이는 보통 모듈 사이에 낮은 결합도를 유지하게 해주지만, 만약 그렇지 않다면 모델을 변경해서 개념을 서로 분리하는 방법을 찾도록 하자. 모듈에는 유비쿼터스 언어의 한 부분을 이루는 이름을 부여하자.

모듈과 이름은 반드시 도메인에 관한 통찰을 반영해야 한다.

​

모듈 설계 예제

ex)

com.myservice.identityaccess.domain

com.myservice.identityaccess.domain.model

com.myservice.identityaccess.domain.service

​

애그리게이트(aggregate)

-> 스크럼 모델링의 핵심이 살아 있는 곳.

각 모델들은 별도의 패키지로 분리하여 관리한다.

​

일관성의 경계 (consistency boundary)

애그리게잇에서 영속성에 따라 가져오는 데이터량이 많다면 메모리 사용량도 고려해야한다.

​

하나의 트랜젝션 -> 일관성 경계

경계의 밖에선 결과적 일관성을 사용하라.

-> transaction 범위를 벗어난 부분에서는 결과로 리턴된 객체를 이용하여 사용하라는 것 같음

​

애그리게잇에게 의존성 주입은 피하라.

​

데메테르의 법칙

그 자신, 자신에게 전달된 매개변수, 자신의 인스턴스화 하는 객체 자신이 직접 엑세스 할 수 있는 스스로가 포함된 파트 객체

​

매개변수로 전달된 객체의 내부 변수들를 바로 접근 할 수 있도록 하는 것을 제한 하고, 전달 받은 객체의 메소드를 이용하여 사용하는 것.

​

​

​

​

This article is licensed under CC BY 4.0 by the author.