도메인 모델의 표준 패턴
다이어그램과 같은 도메인 모델을 그리기 위해서 알아야 될 도메인 모델의 표준 패턴에 대해 알아보도록 하겠습니다.
전술적 설계를 위한 모델 주도 설계의 내비게이션 맵으로 도메인 모델을 위해 사용하는 표준 패턴과 각 패턴과의 관계를 나타낸 그림입니다. 이런 표준 패턴을 사용해서 도메인 모델링을 하게 되면 다른 사람의 업무, 다른 팀의 업무를 쉽게 이해할 수 있는 설계의 체계를 가져갈 수 있습니다.
따라서 훌륭한 도메인 모델을 개발하기 위해 화면과 같은 표준 패턴에 대해 이해를 하고 있어야 됩니다. 계층형 아키텍처와 도메인 모델의 표준 패턴, 도메인을 표현하기 위한 표준 패턴 중 전술적 설계에서 반드시 이해해야 되는 패턴들이 있습니다.
계층형 아키텍처
소프트웨어를 만들 때 개발되는 시스템은 도메인과 관련된 영역 외에도 사용자 인터페이스와 애플리케이션 그리고 인프라스트럭처 등과 관련된 많은 코드들이 포함됩니다. 그런데 도메인과 관련된 기능이 다른 관련이 없거나 적은 기능과 섞여 있을 수 있습니다. 이 때, 코드의 가독성도 떨어지고 UI나 데이터베이스 등의 변화에도 비즈니스 로직에 영향을 많이 주게 됩니다.
따라서 시스템에서는 도메인과 관련이 적은 기능으로부터 도메인을 격리시켜 순수한 도메인 모델을 갖도록 하는 것이 중요합니다. 이와 같이 복잡한 프로그램은 4개의 영역으로 나눠져야 합니다. 각 계층은 계층별로 높은 응집성을 갖도록 만들어져야 되고, 또한 각 계층은 하위의 계층에만 의존하게 하는 등 상호작용을 위한 규칙들이 정해져야 됩니다.
도메인 주도 설계에서는 이러한 분리를 위해 계층형 아키텍처 기법을 적용하고 있습니다. 4개의 계층 중 사용자와의 접점에 위치해 있는 사용자 인터페이스는 사용자의 입력을 받아 애플리케이션 계층에 전달하는 기능을 합니다. 애플리케이션 계층은 애플리케이션이 수행할 작업을 정의하고 조정합니다. 하위 계층인 도메인 객체로 작업을 전달하는 역할을 합니다.
도메인 계층은 비즈니스의 로직이 위치합니다. 업무용 소프트웨어의 핵심으로 상위 계층에서 전달받은 업무의 처리를 위한 업무 정보와 업무 규칙을 표현합니다. 마지막으로 인프라스트럭처 계층은 데이터의 저장이나 메시지 시스템 등의 상위 계층을 지원하는 기능을 제공합니다.
이런 계층형 아키텍처에서는 계층의 모든 요소는 같은 계층 또는 하위 계층에서만 의존합니다. 상위로의 의존은 콜백 또는 옵저버 패턴 등을 활용합니다. 간접적인 메커니즘을 반드시 거쳐야 됩니다. 도메인 주도 설계에서는 도메인 계층을 분리하는 것이 매우 중요합니다. 도메인의 다른 기능과 분리해야 도메인의 설계에만 집중을 할 수 있게 되기 때문입니다.
엔티티
여러 요소 중에서 모델을 표현하는 것에는 엔티티와 값 객체 그리고 서비스가 있습니다. 특히 소프트웨어의 상태가 변경되더라도 식별자를 통해 다른 객체와 식별되어야 할 때 이를 엔티티로 설계를 하게 됩니다.
엔티티는 객체의 생명주기 동안 형태나 내용이 변경될 수 있지만, 그 연속성은 유지되는 특성을 갖고 있습니다. 엔티티는 이렇게 고유한 식별자와 변화 가능성이라는 특징을 갖습니다. 이것이 엔티티와 값 객체를 구분하는 중요한 차이점입니다.
값 객체
엔티티와 같이 모델을 표현하고 있습니다. 엔티티와는 다르게 식별성이 없는 것이 값 객체입니다. 값 객체는 상태를 변경할 수 없는 객체로 어떤 것을 나타낸다기보다는 엔티티를 서술하고 수량화하거나 측정하는 속성으로 사용됩니다.
값 객체는 불변성이 유지될 수 있도록 모델링되어야 합니다. 개별 속성의 수정/삭제 되지 않고 전체 값 객체가 생성/삭제 되는 방식으로 동작하게 됩니다. 도메인의 관리는 객체의 생명주기 동안 무결성을 어떻게 유지할 것인지, 생명주기 관리를 위해 객체의 관계가 복잡해지는 것을 어떻게 최소화할 것인지에 대해 해결하는 것이 중요합니다.
애그리게잇
애그리게잇은 업무상 관련 있는 객체들을 모아 경계를 명확히 정의합니다. 객체 간 관계를 복잡하지 않게 함으로써 생명주기 상의 전 단계에서 도메인 객체의 무결성을 유지할 수 있게 해주는 패턴입니다.
데이터 변경의 단위로 다루는 연관된 객체의 묶음이라고 설명할 수 있습니다. 하나의 트랜잭션은 오직 하나의 애그리게이션만을 수정하고 커밋한다는 원칙을 갖고 있습니다. 그런 이유로 애그리게잇을 트랜잭션의 일관성을 만드는 경계라고 정의하기도 합니다.
따라서 트랜잭션의 일관성과 성공을 보장하도록 애그리게이션 구성요소들을 설계하는 것이 중요합니다. 애그리게잇은 1개 이상의 엔티티로 구성되며, 그 중 한 엔티티는 애그리게잇 루트로 정의되어 구성되며, 값 객체를 포함시킬 수 있습니다.
각 애그리게잇은 일관성 있는 트랜잭션의 경계를 형성합니다. 이는 트랜잭션의 제어가 데이터베이스에 커밋될 때 한 애그리게잇 내의 모든 구성요소들은 비즈니스 규칙을 따릅니다. 그리고, 일관성 있게 처리된다는 것이 애그리게잇의 설계 규칙입니다.
그런 이유로 애그리게잇을 트랜잭션의 일관성을 만드는 경계라고 부릅니다. 트랜잭션 일관성과 성공을 보장하도록 애그리게잇의 구성요소들을 설계해야 됩니다. 즉, 애그리게잇2는 애그리게잇1로부터 분리된 트랜잭션으로 제어되어야 한다는 것을 의미합니다.
리파지토리
애그리게잇의 개념적인 저장소, 필요한 객체에 접근하기 위한 진입점을 리파지토리라고 합니다. 도메인 계층의 데이터 저장을 위한 인터페이스를 구현하고, 실제 저장 기능은 인프라스트럭처 계층에 위치하게 됩니다. 이렇게 인터페이스를 도메인 계층에 구현함으로써 도메인 계층은 데이터베이스 기술의 변경에도 추가적인 변경이 필요 없게 되어 도메인 계층이 비즈니스를 처리하는 일에만 집중할 수 있게 해줍니다.
하나의 Bounded Context 내부의 변경이 다른 Bounded Context로 파생되는 작업이 필요한 경우 비동기 방식의 도메인 이벤트를 통해 명시적으로 구현할 수도 있습니다. 도메인 이벤트는 메시지 큐를 사용한 비동기 방식으로 동작하며, 결과적 데이터의 일관성을 보장하게 됩니다. 이런 비동기 방식의 도메인 이벤트를 사용합니다. 각 Bounded Context는 다른 Bounded Context와의 의존도를 낮출 수 있습니다.
즉, 서로 다른 도메인이 섞이는 것을 방지할 수 있다는 것을 의미합니다. 여기서 데이터의 일관성이란 일관성을 유지시켜야 되는 데이터가 일정한 시간 다른 데이터와 일치하지 않을 수도 있습니다. 하지만, 어느 시점이 되면 결국 일치하게 된다는 것을 의미합니다.
'SW > 마이크로서비스' 카테고리의 다른 글
마이크로서비스 : 쇼핑몰 서비스 : 첫번째 설계 이야기 (0) | 2020.05.14 |
---|---|
마이크로서비스 : 전략적 설계의 정의, 이벤트 스토밍 : 개념, 정의, 개요 (0) | 2020.05.13 |
마이크로서비스 : 전략적 설계 : 컨텍스트 매핑 : 정의, 개요, 개념 (0) | 2020.05.12 |
마이크로서비스 : 전략적 설계 : 바운디드컨텍스와 유비쿼터스 : 개념, 정의, 개요 (0) | 2020.05.12 |
마이크로서비스 : 도메인 주도 설계 : 개념, 정의, 개요 (2) (0) | 2020.05.11 |