
도메인 모델
비즈니스 이해를 위한 특정 비즈니스 영역의 개념, 규칙, 정의를 객체 모델로 표현한 것
도메인 모델의 구성 요소
Ubiquitous Language
기획자, 개발자, 도메인 전문가가 공용으로 사용하는 언어
Entity
식별자를 지닌 도메인 객체
// 엔티티
public class Event { // 도메인 객체
// 식별자
private Long eventId; // 이벤트 마다 배정된 구별 아이디
private String title;
private EventPeriod period;
@OneToMany
private EventPrize prize;
...
}
// 엔티티
public class EventPrize { // 도메인 객체
// 식별자
private Long eventPrizeId; // 이벤트 상품마다 배정된 구별 아이디
private String name;
...
}
// 엔티티
public class Participate { // 도메인 객체
// 식별자
private Long participateId; // 참석 번호
private Long userId; // 회원 식별자
private Long eventId; // 이벤트 식별자
private LocalDateTime participateDt; // 참석 일자
...
}
// 엔티티
public class Winner { // 도메인 객체
// 식별자
private Long winnerId; // 당첨 번호
private Long userId; // 회원 식별자
private Long eventId; // 이벤트 식별자
...
}Value Object
식별자 없이 속성으로 구별되는 불변의 객체, 엔티티의 일부로 포함된다
@Embeddable → 이 클래스는 다른 클래스 내에 필드로 포함될 수 있다
@Embedded → 포함 되었다
// 엔티티
public class Event {
// 식별자
private Long eventId; // 이벤트 마다 배정된 구별 아이디
private String title; // 이벤트 제목 (그냥 값)
@OneToMany
private EventPrize prize;
@Embedded
private EventPeriod period; // 이벤트의 기간
}
// 엔티티
public class EventPrize { // 도메인 객체
// 식별자
private Long eventPrizeId; // 이벤트 상품마다 배정된 구별 아이디
private String name;
...
}
// 엔티티
public class Participate { // 도메인 객체
// 식별자
private Long participateId; // 참석 번호
private Long userId; // 회원 식별자
private Long eventId; // 이벤트 식별자
private LocalDateTime participateDt; // 참석 일자
...
}
// 엔티티
public class Winner { // 도메인 객체
// 식별자
private Long winnerId; // 당첨 번호
private Long userId; // 회원 식별자
private Long eventId; // 이벤트 식별자
...
}
// 값 객체
@Embeddable
public class EventPeriod {
// 불변
private LocalDateTime StartDt;
private LocalDateTime EndDt;
}Aggregate
관련 객체를 하나의 단위로 묶은 것
외부에서는 Aggregate 의 Root 로 접근 (트랜잭션을 지녀야 한다)
public class Event { // 도메인 객체
// 식별자
private Long eventId; // 이벤트 마다 배정된 구별 아이디
private String title;
@OneToMany
private EventPrize prize;
@Embedded
private EventPeriod period;
...
}
// 엔티티
public class EventPrize { // 도메인 객체
// 식별자
private Long eventPrizeId; // 이벤트 상품마다 배정된 구별 아이디
private String name;
...
}
@Embeddable
public class EventPeriod {
// 불변
private LocalDateTime StartDt;
private LocalDateTime EndDt;
}
// 이 전체가 하나의 Event 애그리거트
// 루트는 Event
// EventPrzie 는 Event 를 통해서 접근한다
// EventPeriod 는 Event 를 통해서 접근한다Bounded Context
어떠한 하위 개념이 어떤 도메인과 의미가 충돌하지 않도록 정하는 경계
// "참여" 라는 행위가 이벤트에서 참여한다 라는 의미로 쓰이나
// 다른 도메인 에서 다른 의미로 사용될 수 있으니 경계를 지어 구분해야함
// 결제의 "상품", 재고의 "상품", 주문의 "상품"은 다른 의미 일수도 있음
// 이럴 경우 유비쿼터스 언어는 일관되게 한 상태로 도메인과의 경계를 지어야하는데
// 여기서 이 경계를 Bounded Context 라고 한다Domain Service
특정 엔티티에 속하지 않는 비즈니스 로직
// 엔티티
public class Event { // 도메인 객체
// 식별자
private Long eventId; // 이벤트 마다 배정된 구별 아이디
private String title;
private EventPeriod period;
...
}
// 엔티티
public class Participate { // 도메인 객체
// 식별자
private Long participateId; // 참석 번호
private Long userId; // 회원 식별자
private Long eventId; // 이벤트 식별자
private LocalDateTime participateDt; // 참석 일자
...
}
// 엔티티
public class Winner { // 도메인 객체
// 식별자
private Long winnerId; // 당첨 번호
private Long userId; // 회원 식별자
private Long eventId; // 이벤트 식별자
...
}
// 이벤트 추첨 로직을 만들어야 한다고 하면
// Event 에 종속되어야 할지
// Participate 에 종속되어야 할지
// Winner 에 종속되어야 할지 모든 것에 연관이 있으니
// 따로 서비스에 비즈니스 로직을 만들어야함Repository
Aggregate를 저장하고 조회하는 인터페이스
public interface EventRepository { // 도메인 객체
Event saveEvent(Event event);
Event getEvent(Long eventId);
List<Event> getAllEvent();
void deleteEvent(Long eventId);
}유의할 사항들
애그리거트와 엔티티의 구별
public class Event { // 도메인 객체
// 식별자
private Long eventId; // 이벤트 마다 배정된 구별 아이디
private String title;
@OneToMany
private EventPrize prize;
@Embedded
private EventPeriod period;
...
}
// 엔티티
public class EventPrize { // 도메인 객체
// 식별자
private Long eventPrizeId; // 이벤트 상품마다 배정된 구별 아이디
private String name;
...
}
// 값 객체
@Embeddable
public class EventPeriod {
// 불변
private LocalDateTime StartDt;
private LocalDateTime EndDt;
}
// Event, EventPrzie -> 엔티티
// Event + EventPrzie + EventPeriod -> 애그리거트
// EventPeriod -> 값 객체도메인 모델링에서 표현하는 것의 정의
연관 관계를 어떻게 생각해야하는 것이 좋을까?
1:N 관계로 생각하면 폭 넓게 도메인 객체를 생각할 수 있을 것
하지만 구현점이 너무 어렵지 않을까N:1 관계로 생각하면 구현점을 작게 나눌 수 있지만
구현할 것들이 많아 지게 될 것
Share article