도메인 주도 설계 첫걸음 - 06장 복잡한 비즈니스 로직 다루기
범위
- [Part 2] 전술적 설계 - 06장: 복잡한 비즈니스 로직 다루기
개념 정리
책에서 기억하고 싶은 내용
배경
- ‘전술적 도메인 주도 설계(tactical domain-driven design)’ 패턴: 도메인 모델
- 그 구성 요소: 애그리게이트, 밸류 오브젝트
도메인 모델
- 도메인 모델 패턴은 복잡한 비지니스 로직을 다루기 위한 것이다.
구현
- 도메인 모델은 행동(behavior)과 데이터(data) 모두를 포함하는 도메인의 객체 모델이다.
- DDD의 전술 패턴인 애그리게이트, 밸류 오브젝트, 도메인 이벤트, 도메인 서비스는 모두 객체 모델의 구성 요소다.
복잡성
- 도메인 비지니스 로직은 이미 본질적으로 복잡하므로 모델링에 사용되는 객체가 모델에 조금이라도 우발적 복잡성을 추가하면 안 된다.
- 모델에는 데이터베이스 또느ㅜㄴ 외부 시스템 구성요소의 호출 구현 같은 인프라 또는 기술적인 관심사를 피해야 한다.
- 모델의 객체는 플레인 올드 오브젝트(plain old object)가 된다.
- 플레인 올드 오브젝트는 인프라 구성요소 또는 프레임워크에 의지하지 않고 직접 협업하지 않으면서 비즈니스 로직을 구현하는 객체다.
유비쿼터스 언어
- 도메인 모델의 객체가 기술적 관심사가 아닌 비즈니스 로직에 집중하게 하면 바운디드 컨텍스트에서 사용하는 유비쿼터스 언어의 용어를 따르기 쉬워진다. 다시 말해, 이 패턴은 코드에서 유비쿼터스 언어를 사용하게 하고 도메인 전문가의 멘탈 모델을 따르게 한다.
구성요소
밸류 오브젝트
- 밸류 오브젝트를 사용하는 설계의 장점
- 명료성 향상
- 유효성 검사 로직이 밸류 오브젝트 자체에 들어 있기 때문에 값을 할장하기 전에 유효성 검사를 할 필요가 없다.
- 밸류 오브젝트를 사용하면 코드에서 유비쿼터스 언어를 사용하게 하므로 코드에서 비즈니스 도메인의 개념을 표현하게 된다.
- 구현
- 밸류 오브젝트는 불변의 객체로 구현되므로 밸류 오브젝트에 있는 필드가 하나라도 바뀌면 다른 값이 생성된다.
- 밸류 오브젝트의 동일성은 id 필드나 참조 대신 값을 기반으로 하므로 동일성 검사 함수를 오버라이드해서 적절히 구현하는 것이 중요하다.
- 밸류 오브젝트를 사용하는 경우
- 밸류 오브젝트는 가능한 모든 경우에 사용하는 게 좋다.
- 밸류 오브젝트는 코드의 표현력을 높여주고 분산되기 쉬운 비즈니스 로직을 한데 묶어줄 뿐만 아니라 코드를 더욱 안전하게 해준다.
- 밸류 오브젝트는 불변이기 때문에 내포된 동작은 부작용과 동시성 문제가 없다.
엔티티
- 엔티티는 밸류 오브젝트와 정반대다.
- 엔티티는 다른 엔티티 인스턴스와 구별하기 위해 명시적인 식별 필드가 필요하다.
- 식별 필드의 핵심 요구사항은 각 엔티티의 인스턴스마다 고유해야 한다.
- 엔티티의 식별 필드의 값은 엔티티의 생애 주기 내내 불변이어야 한다.
- 밸류 오브젝트와는 반대로, 엔티티는 불변이 아니고 변할 것으로 예상된다.
- 밸류 오브젝트는 엔티티의 속성을 설명한다.
애그리게이트
- 애그리게이트는 엔티티다. 즉, 명시적인 식별 필드가 필요하고 인스턴스의 생애주기 동안 상태가 변할 것으로 예상된다.
- 일관성 강화
- 데이터의 일관성을 강화하려면 애그리게이트 패턴에서는 애그리게이트 주변에 명확한 경계를 설정해야 한다. 즉, 애그리게이트는 일관성을 강화하는 경계다.
- 애그리게이트의 퍼블릭 인터페이스로 노출된 상태 변경 메서드는 ‘어떤 것을 지시하는 명령’을 뜻하는 의미에서 커맨드라고도 부른다.
- 애그리게이트의 퍼블릭 인터페이스는 입력값의 유효성을 검사하고 관련된 모든 비즈니스 규칙과 불변성을 강화하는 것을 담당한다.
- 트랜젝션 경계
- 애그리게이트의 상태는 자신의 비즈니스 로직을 통해서만 수정될 수 있기 때문에 애그리게이트가 트랜젝션 경계의 역할을 한다.
- 모든 애그리게이트 상태 변경은 원자적인 단일 오퍼레이션으로 트랜젝션 처리돼야 한다.
- 애그리게이트의 상태가 수정되면 모든 변경이 커밋되거나 모두 원래 상태로 돌아가야 한다.
- 엔티티 계층
- 엔티티는 독립적인 패턴이 아닌 애그리게이트의 일부로서만 사용된다.
- 다른 애그리게이트 참조하기
- 애그리게이트 루트
- 애그리게이트가 엔티티의 계층 구조를 대표하기 때문에 그 중 하나만 애그리게이트의 퍼블릭 인터페이스, 즉, 애그리게이트 루트로 지정돼야 한다.
- 도메인 이벤트
- 도메인 이벤트는 비즈니스 도메인에서 일어나는 중요한 이벤트를 설명하는 메시지다.
- 유비쿼터스 언어
- 애그리게이트는 유비쿼터스 언어를 사용해야 한다.
도메인 서비스
- 도메인 서비스는 비즈니스 로직을 구현한 상태가 없는 객체(stateless object)다.
복잡성 관리
- 애그리게이트와 밸류 오브젝트 패턴의 역할: 복잡한 것을 불변성으로 감싸서 복잡성을 낮추는 것.
결론
- 밸류 오브젝트
- 값만으로 식별되는 비즈니스 도메인의 개념
- 애그리게이트
- 트랜잭션 경계를 공유하는 엔티티의 계층
- 애그리게이트의 경예에 속하는 모든 데이터는 비즈니스 로직의 구현을 통해 강력한 일관성을 유지해야 한다.
- 도메인 서비스
- 도메인 모델에서 애그리게이트 또는 밸류 오브젝트에 속하지 않는 비즈니스 로직을 담는 상태가 없는 객체(stateless object)
This post is licensed under CC BY 4.0 by the author.