Domain Model Design
이 page는 도메인 모델을 입력과 출력의 편의가 아니라, 문제 영역의 규칙·상태·연산을 코드의 객체와 관계로 표현하는 설계로 해석한다. 원문의 로또 예제에서는 티켓, 당첨 번호, 당첨 결과처럼 규칙을 가진 대상을 별도 객체로 두고, 구매와 당첨 계산의 흐름은 Service가 조합한다.[1]
모델이 책임질 것
- 원문은
Value Object를 불변이고 동등성을 값 기준으로 판단하는 객체로 두며, 예제의Lotto는 생성자에서validate(numbers)로 유효성을 확인한다.[1:1] 번호의 개수·범위·중복 금지 규칙은 원문의 기능 목록(1~45, 6개, 중복 없음)에 나오고, 이를Lotto의 불변식으로 관리한다고 연결하는 것은 이 page의 해석이다.[1:2] - 등수나 상금처럼 닫힌 도메인 상수는
Enum으로 표현해 이름, 조건, 보상 값을 함께 둔다.[1:3] - 모델의 연산은 데이터만 노출하기보다 의미 있는 질문으로 드러낸다. 예를 들어
WinningNumbers가match(Lotto)로 티켓과 비교해 등수(WinningCriteria)를 판정하고,WinningService.calculate가 결과를Statistics로 돌려주는 식이다.[1:4]
Application 흐름과의 경계
flowchart LR
I[입력] --> C[Controller]
C --> LS[LottoService: 구매 흐름]
C --> WS[WinningService: 당첨 계산]
LS --> L[Lotto / Tickets]
WS --> L
WS --> S[Statistics]
S --> O[출력]LottoService는 구매 금액에서 티켓 목록을 만드는 use case를,WinningService는 티켓과 당첨 번호에서 통계를 계산하는 use case를 맡는다.[1:5]- Controller는 입력 순서와 출력 흐름을 조율하고,[1:6] 번호 중복·범위 같은 도메인 규칙을 직접 판정하지 않는다.[2]
- 이 분리는 Service가 도메인 객체를 대체한다는 뜻이 아니다. Service는 여러 모델의 작업을 연결하고, 규칙과 불변식은 가능한 한 모델 가까이에 둔다고 해석할 수 있다.
설계 점검 질문
- 새 규칙이 생겼을 때 Controller의 조건문이 아니라 도메인 객체의 생성·행위로 표현되는가?
- 값에 대한 제약이 여러 Service에 복제되지 않고 하나의 Value Object에 모이는가?
- Service 이름이 기술 동작보다 사용자 시나리오(구매, 당첨 계산)를 드러내는가?
관련
- Layered Application Boundary: Controller·Service·Domain의 책임 경계를 적용하는 구조다.
- First Class Collection: 여러 도메인 객체의 집합과 그 규칙을 모델 안에 모으는 한 방식이다.
- Custom Exception Design: 모델의 불변식 위반을 구체적인 오류로 전달할 때 사용한다.
출처
도메인 모델 설계 — 로또 시스템의 클래스 관계, Value Object·Enum·Service 분리, Controller 처리 흐름을 제시한다. "불변, 동등성이 값 기준"(L84), "validate(numbers);"(L91), "당첨 번호 입력 (1~45, 6개, 중복 없음)"(L148), "로또 번호 생성 (1~45 중 6개 랜덤)"(L153) ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎
레이어드 아키텍처 — 레이어 책임표: "| Controller | 흐름 제어, try-catch | 도메인 로직 직접 처리 |"(L27), "| Domain | 핵심 규칙, 불변식 | 외부 의존성 |"(L29) ↩︎