◆ 도메인 모델링
▶ 마이크로서비스의 내부 구조는 폴리글랏하게 접근할 수 있는데 폴리글랏하다 라는 의미는 애플리케이션을 구현하는 언어나 데이터를 저장하는 저장소를 서비스마다 다양하게 활용할 수 있다는 의미인 동시에 내부 아키텍처 구조를 서비스 특성에 맞게 다양하게 수립할 수 있다는 의미이기도 하므로 서비스의 내부 영역의 구조를 도메인 모델 중심으로 만들 수도 있고 트랜잭션 스크립트 형태로 만들 수도 있음
▶ 도메인 모델 형태의 헥사고날 구조
▶ 단순한 로직인 경우에는 트랜잭션 스크립트 구조로 만들어도 무방하지만 비즈니스가 복잡해질수록 비즈니스 개념들을 잘 구조화할 수 있는 도메인 모델 구조가 효과적
▶ 도메인 모델 구조는 복잡함을 다루어 쉽게 표현할 수 있는 구조를 제공하기 때문인데 이러한 내부 구조를 정의하려면 서비스가 제공할 기능이 어떠한 가도 고민해야겠지만 팀의 역량 수준도 고려해야 함
▶ 백엔드 엔지니어가 객체지향 설계 및 문화에 능숙한지 여부를 판단해야함
▶ 마이크로서비스의 내부 영역을 도메인 모델 구조로 정의했을 때 설계하는 방식이 도메인 모델링
▶ DDD의 전술적 설계(도메인 모델링 구성요소)
● 기존 객체 모델링 방식은 자유도가 높아 문제 영역을 파고들수록 여러 층의 복잡한 계층 구조를 만들게 될 가능성이 높아서 이를 정리하기 위해 객체들의 역할에 따른 유형을 정의하고 이러한 규칙에 따라 모델링하면 단순하고 이해하기가 수월해지는데 이러한 설계 기법을 DDD 의 전술적 설계에서 제공
● 엔티티
⊙ 엔티티는 다른 엔티티와 구별할 수 있는 식별자를 가진 도메인의 실체 개념을 표현하는 객체
⊙ 식별자는 고유하되 엔티티의 속성 및 상태는 계속 변할 수 있음
⊙ 도메인에서 개별성 (individuality)이 있는 개념을 엔티티로 식별하며 고유 식별자 와 변화 가능성(mutability)이 엔티티와 값 객체를 구분하는 차이점
⊙ 구매는 구매번호라는 식별자로 구분 가능하며 구매품이나 수취자 등이 개별적으로 변경될 수 있으므로 엔티티로 모델링
● Value Object
⊙ 값 객체는 각 속성이 개별적으로 변화하지 않는 개념적 완전성 을 모델링
⊙ 값 객체는 속성과 속성의 합에 의해 전체 개념이 부여되며 개별 속성이 별개로 수정되지 않고 전체 객체가 한 번에 생성되거나 삭제되는 객체
⊙ 엔티티와 같이 식별자의 차이에 따라 구별되지 않고 속성과 속성으로 이뤄진 값의 비교에 의해 동일함이 결정
⊙ 도메인 주도 설계 핵심의 저자 반 버논(Vaughn Vernon)은 값 객체의 특성을 다음과 같이 정의
→ 도메인 내의 어떤 대상을 측정하고, 수량화하고, 설명
→ 관련 특징을 모은 필수 단위로 개념적 전체를 모델링
→ 측정이나 설명이 변경될 땐 완벽히 대체 가능
→ 다른 값과 등가성을 사용해 비교할 수 있음
→ 값 객체는 일단 생성되면 변경할 수 없음
⊙ 구매자, 수취자, 구매품 등은 구매를 구성하는 속성을 표현하는 개념이므로 값 객체로 모델링
⊙ 구매품의 개별 속성들은 별도로 변경되지 않고 구매품 전체가 추가되거나 삭제만 가능
● 표준 타입
⊙ 표준 타입은 대상의 타입을 나타내는 서술적 객체
⊙ 엔티티나 값 객체의 속성을 구분하는 용도로 사용
⊙ 전화번호를 값 객체로 모델링했다면 이 전화번호가 집 전화인지 핸드폰 전화 또는 회사 전화번호인지 구분할 필요가 있음
⊙ 예전에는 보통 코드 값으로 모델링했으나 이러한 방식은 매핑표가 필요하며 가독성이 떨어져 이해하기 어려운데 컨텍스트에 맞는 이해 가능한 유비쿼터스 용어로 정의하는 것이 바람직
⊙ 자바 언어에서는 보통 열거형으로 정의
⊙ 멤버십 등급 유형이라는 열거형으로 VIP, GOLD, SILVER로 구분해서 표준 타입으로 정의
● 애그리거트
⊙ 엔티티 와 값 객체로 모델링하게 되면 자연스럽게 객체 간의 계층 구조가 만들어지는데 이처럼 연관된 엔티티 와 값 객체들의 묶음이 애그리거트
⊙ 애그리거트는 1〜2개의 엔티티, 값 객체, 표준 타입 등으로 구성되는데 이들 간에는 비즈니스 의존 관계를 맺고 있으며 비즈니스 정합성을 맞출 필요가 있어서 이 애그리거트 단위가 트랜잭션의 기본 단위가 됨
⊙ 애그리거트 내에 있는 엔티티 중 가장 상위의 엔티티를 애그리거트 루트로 정하고 이 애그리거트 루트를 통해서만 애그리거트 내의 엔티티나 값 객체를 변경할 수 있음
⊙ 하나의 컨텍스트에 하나의 애그리거트가 식별되나 하나의 컨텍스트 안에 여러 개의 애그리거트가 존재할 수 있는데 이 경우 다른 애그리거트를 참조해야 할 필요가 있다면 직접 참조하지 않고 참조할 애그리거트 루트의 식별자를 통해 참조하게 하는데 직접 참조하는 경우 애그리거트 단위의 트랜잭션 처리도 힘들고 의존관계가 점점 복잡해질 것이기 때문
⊙ 일반적으로 바운디드 컨텍스트를 마이크로서비스로 식별하게 되는데 애그리거트 또한 별도의 마이크로서비스 후보가 될 수 있는데데 같은 컨텍스트 내에 여러 개의 애그리거트가 존재할 때 다른 애그리거트의 클래스를 직접 참조하면 별도로 마이크로서비스로 분리하기 힘들 것이므로 애그리거트 간 참조는 애그리거트 루트의 식별자를 활용해 간접 참조하는 것이 바람직
⊙ 식별자를 통한 애그리거트 간 참조
⊙ 각 애그리거트는 각각의 단일 트랜잭션으로 일관성을 유지하고 다른 애그리거트 사이의 일관성이 필요한 경우에는 도메인 이벤트를 통한 결과적 일관성을 사용해 다른 애그리거트를 갱신해서 일관성을 유지
● 도메인 서비스
⊙ 도메인의 비즈니스 로직 처리가 특정 엔티티나 값 객체에 속하지 않을 때 단독 객체를 만들어서 처리하게 하는데 이를 도메인 서비스라 함
⊙ 도메인 서비스에서는 상태를 관리하지 않고 행위만 존재하기 때문에 도메인 로직을 처리할 때 엔티티나 값 객체와 함께 특정 작업을 처리하고 상태를 본인이 가지고 있지 않고 엔티티나 값 객체에 전달
● 도메인 이벤트
⊙ 도메인 이벤트는 DDD 및 이벤트 스토밍에서 말하는 도메인 이벤트의 구현 객체
⊙ 서비스 간 정합성을 일치시키기 위해 단위 애그리거트의 주요 상태 값을 담아 전달되도록 모델링
댓글