샘플 애플리케이션 도메인 엔티티 및 테이블 설계
도메인에서 애그리거트 루트 찾기
[그림 3-43]은 우리가 이번 챕터에서 Spring Data JDBC를 이용해서 구현해야 할 커피 주문 샘플 애플리케이션의 도메인 모델입니다.
우리가 구현하는 커피 주문 샘플 애플리케이션은 학습용이기 때문에 결제, 배송과 같은 도메인은 필요하지 않습니다. 따라서 굉장히 심플한 도메인 모델로 설계되었습니다.
✔ 변경된 요구 사항
그리고 이 전 챕터까지는 기술의 이해를 위해 한 명의 회원이 하나의 커피만 주문한다라고 가정하고 학습을 진행 했지만 이번 챕터부터는 한명의 회원이 하나 이상의 커피를 주문할 수 있는 요구 사항이 반영되기 때문에 [그림 3-43]과 같은 도메인 모델이 도출 되었습니다.
세 개의 애그리거트(Aggregate)가 정의 되었고, 각 애그리거트((Aggregate)마다 애그리거트 루트(Aggregate Root)가 결정된 것을 볼 수 있습니다.
애그리거트 간의 관계
각 애그리거트 간의 관계는 1과 N(1이상)으로 표시했습니다.
- 회원 정보(Member)와 주문 정보(Orders)의 관계(1 대 N)
- 한 명의 회원은 여러 번 주문을 할 수 있습니다.
- 주문 정보(Orders)와 커피 정보의 관계(N 대 N)
- 하나의 주문은 여러 종류의 커피를 가질 수 있습니다.
- 하나의 커피는 여러 건의 주문에 속할 수 있습니다.
- N 대 N의 관계는 일반적으로 1 대 N, N 대 1의 관계로 재 설계 되기 때문에 아래와 같이 변경됩니다.
- 주문 정보(Orders)와 주문 커피 정보(Order_Coffee): 1 대 N
- 주문 커피 정보(Order_Coffee)와 커피 정보(Coffee): N 대 1
엔티티 클래스 간의 관계
이제 이 애그리거트를 기준으로 도메인 엔티티 클래스 간의 관계를 클래스 다이어그램을 통해 구체적으로 표현해 보겠습니다.
[그림 3-44]는 커피 주문 샘플 애플리케이션의 도메인 엔티티 클래스의 관계를 클래스 다이어그램으로 표현한 것입니다.
각각의 엔티티 클래스를 간단하게 살펴보겠습니다.
- 회원(Member) 엔티티 클래스
- Member 클래스와 Order의 관계는 1 대 N의 관계이기 때문에 Member 클래스에List<Order> 가 추가되었습니다.
- 한 명의 회원은 여러 건의 주문을 할 수 있습니다. 따라서 하나의 Member 클래스에 여러건의 주문이 포함된 List<Order> 를 멤버 변수로 추가했습니다.
데이터베이스 테이블 간의 관계는 외래키를 통해 맺어지지만 클래스 간의 관계는 객체의 참조를 통해 맺어진다는 사실을 기억하기 바랍니다.
- 주문(Order) 엔티티 클래스
- Order 클래스와 Coffee 클래스는 N 대 N의 관계를 가지기 때문에 N 대 N의 관계를 1 대 N의 관계로 만들어주는 List<OrderCoffee>를 멤버 변수로 추가했습니다.
- 커피(Coffee) 엔티티 클래스
- Coffee클래스와 Order 클래스는 N 대 N의 관계를 가지기 때문에 N 대 N의 관계를 1 대 N의 관계로 만들어주는 List<OrderCoffee>를 멤버 변수로 추가했습니다.
- 주문_커피(OrderCoffee) 테이블
- Order 클래스와 Coffee 클래스가 N 대 N 관계이므로 두 클래스의 관계를 각각 1 대 N의 관계로 만들어주기 위한 OrderCoffee 클래스가 추가 되었습니다.
- 주문하는 커피가 한 잔 이상일 수 있기때문에 quantity(주문 수량) 멤버 변수를 추가했습니다.
이 외에 추가적으로 더 필요한 멤버 변수들이 있지만 필요하다면 학습을 진행하면서 그때 그때 추가하도록 하겠습니다.
‘도대체 애그리거트(Aggregat)를 왜 구분하고, 애그리거트 루트(Aggregate Root)는 왜 찾는거며, 엔티티 클래스 간의 관계를 왜 정의하는거야?’ 라고 생각할 수 있습니다.
이유는 여러분들이 지금 ORM 기반의 데이터 액세스 기술인 Spring Data JDBC를 학습하고 있기 때문입니다.
ORM(Object-Relational Mapping)은 말 그대로 객체와 테이블을 매핑하는 기술이기 때문에 앞에서 했던 것처럼 클래스 간의 연관 관계를 찾을 수 밖에 없습니다.
특히나 애그리거트 루트(Aggregate Root)는 Spring Data JDBC가 DDD와 밀접한 관련이 있기 때문에 여러분들이 Spring Data JDBC 기술을 사용하기 위해서는 도메인 모델을 잘 정의하고 애그리거트 루트(Aggregate Root)를 찾아야합니다.
이 애그리거트 루트(Aggregate Root)를 통해 프로그래밍 코드 상에서의 구현 방법이 달라지는데, 이 부분은 이어지는 챕터에서 샘플 애플리케이션을 구현하며 다시 설명하겠습니다.
마지막으로 도메인 엔티티 간의 관계를 기준으로 데이터베이스의 테이블을 설계해봅시다.
데이터베이스 테이블 설계
[그림 3-45]는 커피 주문 샘플 애플리케이션의 도메인 엔티티 클래스 간의 관계를 토대로 만든 데이터베이스의 테이블 설계입니다.
도메인 엔티티 클래스 간의 관계는 객체의 참조로 이루어지지만 테이블 간의 관계는 여러분이 이미 알고 있는 외래키(Foreign key) 참조로 이루어집니다.
각 테이블의 컬럼은 엔티티 클래스의 멤버 변수와 매핑 되므로 설명은 생략하겠습니다.
주문 테이블의 이름이 ‘ORDER’가 아니라 ‘ORDERS’인 이유
이미 눈치챈 분들도 있겠지만 ‘ORDER’는 SQL 쿼리문에서 테이블의 로우(Row)를 정렬하기 위해 사용하는 ‘ORDER BY’라는 예약어에 사용되기 때문에 테이블이 생성될 때 에러를 발생할 수 있습니다.
자, 이제 Spring Data JDBC를 적용하기 위한 설계가 끝났습니다.
이제 이 설계를 토대로 이제껏 학습을 진행하면서 만들어왔던 커피 주문 애플리케이션에 Spring Data JDBC를 적용해 볼까요? ^^
핵심 포인트
- DDD(Domain Driven Design, 도메인 주도 설계)는 도메인 위주의 설계 기법이다.
- 도메인(Domain)이란?
- 애플리케이션 개발에서 사용하는 도메인이란 용어는 주로 비즈니스적인 어떤 업무 영역과 관련이 있다.
- 애플리케이션을 구현하기 위해 필요한 업무들을 자세히 알면 알수록 퀄리티가 높은 애플리케이션을 만들 가능성이 높다.
- 비즈니스 업무 영역을 의미하는 도메인 지식(Domain Knowledge)들을 서비스 계층에서 비즈니스 로직으로 구현해야 한다.
- 애그리거트(Aggregate)와 애그리거트 루트(Aggregate Root)는 DDD에서 사용되는 용어이다.
- 애그리거트(Aggregate)란 비슷한 업무의 하위 수준 도메인들의 묶음을 의미한다.
- 애그리거트 내의 대표 도메인을 DDD에서는 애그리거트 루트(Aggregate Root)라고 한다.
- 애그리거트 루트의 선정 기준
- 각 애그리거트 내의 도메인들 중에서 다른 모든 도메인들과 직간접적으로 연관이 되어 있는 도메인이 애그리거트 루트가 된다.
- 데이터베이스 테이블 간의 관계는 외래키를 통해 맺어지지만 클래스끼리 관계는 객체의 참조를 통해 관계가 맺어진다.
'TIL' 카테고리의 다른 글
[SpringMVC][HTTP헤더] (0) | 2022.10.30 |
---|---|
[Spring Data JDBC][DDD] (0) | 2022.10.28 |
[SpringMVC][Spring Data JDBC] (0) | 2022.10.27 |
[SpringBoot][SpringBoot란?] (0) | 2022.10.22 |
[SpringFramework][Architecture] (0) | 2022.10.22 |