도메인 모델을 사용하면 여러 관계자들이 동일한 모습으로 도메인을 이해하고 도메인 지식을 공유하는데 도움이 된다.
도메인 모델은 기본적으로 도메인 자체를 이해하기 위한 개념 모델이다. 개념 모델을 이용해서 바로 코드를 작성할 수 없기 때문에 구현 기술에 맞는 구현 모델이 필요하다.(객체 기반 모델 ⇒ 객체 지향 언어를 이용)
하위 도메인이 다루는 영역은 서로 다르기 때문에 같은 용어라도 하위 도메인마다 의미가 달라질 수 있다. 따라서 도메인을 이해하는데 방해되기 때문에, 여러 하위 도메인을 하나의 다이어그램에 모델링하면 안된다. 모델의 각 구성요소는 특정 도메인을 한정할 때 비로소 의미가 완전해지기 때문에, 각 하위 도메인마다 별도로 모델을 만들어야 한다.
도메인 모델 패턴
일반적인 애플리케이션 아키텍쳐는 네 개의 계층으로 구성된다.
표현(사용자 인터페이스) : 사용자 요청을 처리하고 사용자에게 정보를 보여준다.
응용(Application) : 사용자가 요청한 기능을 실행한다. 업무 로직을 직접 구현하지 않으며 도메인 계층을 조합해서 기능을 실행한다.
도메인 : 시스템이 제공할 도메인의 규칙을 구현한다.
인프라스트럭처(Infrastructure) : 데이터베이스나 메시징 시스템과 같은 외부 시스템과의 연동을 처리한다.
도메인 모델은 아키텍처상의 도메인 계층을 객체 지향 기법으로 구현하는 패턴을 말한다.
도메인 계층은 도메인의 핵심 규칙을 구현하고, 도메인 규칙을 객체 지향 기법으로 구현하는 패턴이 도메인 모델 패턴이다.
핵심 규칙을 구현한 코드는 도메인 모델에만 위치하기 때문에, 규칙이 바뀌거나 확장해야 할 때 다른 코드에 영향을 덜 주고 변경 내역을 모델에 반영할 수 있게 된다.
도메인 모델 도출
도메인 모델링할 때 기본이 되는 작업은 모델을 구성하는 핵심 구성요소, 규칙, 기능을 요구사항에서 찾는 것이다.
엔티티와 밸류
도출한 모델은 크게 엔티티와 밸류로 구분할 수 있다.
엔티티
엔티티의 가장 큰 특징은 고유한 식별자를 갖는다는 것이다.
엔티팅 식별자는 바뀌지 않으며, 삭제할 때까지 유지된다.
엔티티 식별자 생성
엔티티 식별자 생성하는 시점은 도메인의 특징과 사용하는 기술에 따라 달라진다.
특정 규칙에 따라 생성
UUID 사용
값을 직접 입력
일련번호 사용(시퀀스 or DB 자동 증가 칼럼 사용)
밸류 타입
개념적으로 완전한 하나를 잘 표현할 수 있다.
밸류 타입을 위한 기능을 추가할 수 있다.
밸류 객체의 상태를 변경할 때는 기존 데이터를 변경하기보다는 변경한 상태를 갖는 새로운 밸류 객체를 생성하는 방식을 선호한다.(불변: 데이터 상태 변경을 제공하지 않는 타입, Immutable)
밸류를 불변 타입으로 사용하면 보다 안전한 코드를 작성할 수 있다.
상태 변경 가능한 객체를 멤버 변수로 가지고 있고 해당 객체를 불변으로 만들고 싶다면, 상태 변경 가능한 객체 주입시 새로운 객체를 생성해야 한다.
엔티티 타입의 두 객체의 동등성은 주로 식별자를 이용하지만, 두 밸류 객체 동등성 유무는 모든 속성을 비교해야 한다.
엔티티 식별자와 밸류 타입
엔티티 식별자는 문자열이 아닌 밸류 타입으로 나타내어 의미를 잘 드러낼 수 있다.
도메인 모델에 set 메서드 넣지 않기
도메인 모델에 get/set 메서드를 무조건 추가하는 것은 나쁜 버릇이다.
특히 set 메서드는 도메인의 핵심 개념이나 의도를 코드에서 사라지게 한다. 상태 변경과 관련된 도메인 지식이 코드에서 사라지게 된다.
set 메서드의 또 다른 문제는 도메인 객체를 생성할 때 완전하지 않은 상태가 될 수 있다는 점이다. 도메인 객체가 불완전한 상태로 사용되는 것을 막으려면, 생성 시점에 필요한 것을 모두 전달해 주어야 한다.(생성자를 통해 필요한 데이터를 모두 받아야 함)
set 메서드를 구현해야 할 이유가 없다면 불변 타입의 장점을 살릴 수 있도록 밸류 타입은 불변으로 구현한다.