도메인 모델 시작하기
도메인이란?
- 소프트웨어로 해결하고자 하는 문제 영역
- 도메인은 하위 도메인으로 나눌 수 있음.
- 도메인의 구성은 요구사항에 따라서 달라짐
도메인 전문가와 개발자간 지식 공유
- 요구사항을 정확하게 파악하는 것이 중요함
- 요구사항을 올바르게 이해하기 위해 필요한것
- 개발자와 전문가가 직접 대화하기
- 이를 위해서 전문가 뿐만아니라 개발자도 도메인에 대해 이해하는 것이 중요함
도메인 모델
- 특정 도메인을 개념적으로 표현한 것
- 여러 관계자들이 동일한 모습으로 도메인을 이해하고 지식을 공유할 수 있음
- 도메인 자체를 이해하기 위한 개념 모델
- 모델은 도메인 마다 별도로 있는 것이 좋음
도메인 모델 패턴
- 일반적인 애플리케이션 아키텍쳐
-
영역 설명 표현(UI) 정보를 보여줌, 요청을 처리(사용자와 직접 상호작용) 응용(App) 기능을 실행하고 도메인 계층을 조합해서 실행함 도메인 시스템이 제공할 도메인 규칙을 구현 인프라스트럭처 DB나 메시징 시스템같은 외부시스템과의 연동을 처리
-
- 도메인 계층은 도메인의 핵심 규칙을 (객체지향으로)구현 -> 도메인 모델 패턴
- 핵심 규칙을 구현한 코드는 모델에만 위치함
- 다른 요소에 영향을 거의 주지않고 수정 추가 할 수 있음
도메인 모델 도출
- 요구사항 => 핵심 구성요소, 규칙, 기능
- 요구 사항을 분석하며 도메인을 구체화 하고 역할을 정하는 과정
- 제약, 규칙 => 요구 사항 분석후 열거형과 같은 자료로 명시 가능함
- 모델 공유시 위키, 화이트 보드 사용이 좋음
엔티티와 벨류
- 엔티티
- 식별자
- 다른 속성이 변경이 되더라도 식별자는 변경되지 않음
- equals 나 hashcode 를 식별자를 기준으로 구현 할 수 있음
- 규칙이나 UUID, nanoID, 일련번호, 사용자릐 입력으로 식별자를 생성함
- 유저가 직접 입력하는 경우에는 검증하는 로직이 필요함
- DB를 사용한다면 일련번호를 사용하는 경우가 많음
- DB에 저장하지 않았다면 식별자를 알 수 없다.
- 식별자
- 밸류
- 개념적으로 완전한 하나
- 예) first Name, last Name을 하나의 Name이라는 Value 타입으로 할 수 있음
- 다양하게 나누어져 있는 속성을 하나로 묶어 깔끔한 코드로 정리 가능
- 꼭 2개 이상의 속성이 들어가지 않더라도 하나의 속성만 있는 VO도 사용가능함
- 속성을 위한 계산을 추가 할 수 있음
- VO는 immutable 불변이다. 데이터 변경을 제공하지 않고 새로 생성해 할 당 한다.
- 비교시 모든 속성이 같은지 확인
- 개념적으로 완전한 하나
- 엔티티 식별자와 밸류 타입
- 식별자를 VO로 사용 할 수 있음.
- VO는 도메인에서 특별한 의미을 나타내는 경우가 많음 => 의미가 더 잘 들어남
- 도메인 모델에 set메서드 넣지 않기
- setOOO 같이 그냥 값을 변경하는 것 말고 Complete와 같이 의미를 가지게 설계하는 것이 중요함
- set메서드는 필드 값만 변경하고 도메인 지식 로직이 사라지게 됨
- 생성자로 모든 값을 받아 도메인이 불완전한 상태로 있지 않게함
- set메서드를 private로 사용한다면 클래스 내부에서 데이터를 변경할 목적으로 사용하는 것
- 즉 외부에서 변경할 목적으로 사용할 수 었음
- VO에는 구현하지 set을 구현 하지않음 불변이기 때문
도메인 용어와 유비쿼터스 언어
- step1 step2 와 같이 추상적인 언어보다는 직관적인 단어 사용
- 관계자 개발자가 모두 공통의 언어를 사용함 -> 유비쿼터스 언어
- 도메인 용어를 찾는 시간을 아까워한다면 코드는 점점 도메인과 멀어지게 됨
아키택쳐 개요
네개의 영역
- 표현 : MVC, JSON, (요청, 응답) | Contrller
- 응용 : 기능 구현 (보통 도메인 로직은 객체에게 위임함) | Service
- 도메인 : 도메인 모델을 구현 | Domain
- 인프라스트럭쳐 | DB, etc..
계층 구조 아키텍쳐
- 상위 계층에서 하위 계층으로의 의존만 존재함
- 조금더 유연하게 적용할 수도 있음
DIP (Dependency Incersion Principle)
- 저수준 모듈이 고수준 모듈의 의존
- 추상화한 인터페이스로 구현하는 것
- 도메인 관점에서 찾아야 됨
- 같은 저수준의 모듈에서 추상화하면 다를 바 없음
- 인프라 영역이 응용과 도메인 영역에 의존
도메인 영역의 주요 구성요소
- DB 모델의 도메인 != 도메인 모델
- 도메인 모델은 도메인 기능을 함께 제공
- 도메인 모델의 엔티티는 데이터와 함꼐 기능을 제공하는 객체 (도메인에서 기능구현, 캡슐화)
- VO 사용할 수 있음 DB에서는 새 테이블로 표현 -> 의미가 안들어남
- 애그리 거트
- 관련 객체를 하나로 묶은 군집
- 상위수준에서 전체 구조를 이해하는 데 도움을 줌
- 루트 엔티티에서 구현해야 할 기능을 제공
- 애그리거트를 숨겨 캡슐화
- 레포지토리
- 애그리거트 단위로 도메인 객체를 저장하고 조회하는 기능을 정의함
- 도메인을 영속화하고 추상화 -> 고수준 모듈
요청 처리 흐름
- 표현 영역 : 요청 데이터를 변환해서 전달
- 응용 서비스 : 도메인 모델 이용해서 기능을 구현
- 레포에 저장 및 조회
- Transactional 사용해야함
인프라스트럭처 개요
- 표현, 응용, 도메인 영역을 지원함
- REST,SMTP,영속성 같은 구현기술, 보조기능을 지원
- 도메인, 응용영역의 인터페이스를 인프라에 구현하는 것이 더 유연하고 테스트하기 쉬움
- But
@Entity @Transecional
같은 코드를 사용하는 것이 훨씬 편함 - 이때는 DIP의 장점을 해치지 않는 범위에서 의존을 가져가야함
모듈구성
- 아키텍쳐의 각 영역은 별도의 패키지에 위치
- 도메인이 크면 도메인 마다 별도 패키지를 구성
- 도메인은 도메인에 속한 애그리거트를 기준으로 다시 패키지를 구성
- 너무 커진 패키지는 분리할려고 노력하는게 좋다
'Java' 카테고리의 다른 글
DDD 응용서비스와 표현 영역 (0) | 2023.06.03 |
---|---|
DDD JPA를 이용한 조회기능 (0) | 2023.05.28 |
DDD - 레포지토리와 모델구현 (0) | 2023.05.28 |
DDD 애그리거트 (0) | 2023.05.28 |
Java Collection FrameWork? (0) | 2023.03.27 |