๐[Spring] ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate)๋ ๋ฌด์์ผ๊น์?
- ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate)๋ ๋๋ฉ์ธ ์ฃผ๋ ์ค๊ณ(Domain-Driven Design, DDD)์์ ์ฌ์ฉํ๋ ๊ฐ๋ ์ผ๋ก, ๋ฐ์ ํ๊ฒ ์ฐ๊ด๋ ๊ฐ์ฒด๋ค์ ํ๋์ ์ผ๊ด์ฑ ์๋ ๋ณ๊ฒฝ ๋จ์๋ก ๋ฌถ์ด ๊ด๋ฆฌํ๋ ๊ทธ๋ฃน์ ์๋ฏธํฉ๋๋ค.
- ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate)๋ ํ๋์ ๋๋ฉ์ธ ๊ฐ๋ ์ ํํํ๊ณ , ๊ฐ์ฒด ๊ฐ์ ๊ด๊ณ๋ฅผ ์บก์ํํ์ฌ ์ผ๊ด๋ ์ํ๋ฅผ ์ ์งํ ์ ์๊ฒ ํด์ค๋๋ค.
๐โโ๏ธ ์บก์ํ(Encapsulation)
๊ฐ์ฒด ์งํ ํ๋ก๊ทธ๋๋ฐ์ ์ค์ํ ๊ฐ๋ ์ค ํ๋๋ก, ๊ฐ์ฒด์ ๋ฐ์ดํฐ์ ์ด๋ฅผ ์กฐ์ํ๋ ๋ฉ์๋๋ฅผ ํ๋์ ๋จ์๋ก ๋ฌถ์ด ์ธ๋ถ์์ ์ง์ ์ ๊ทผํ์ง ๋ชปํ๋๋ก ์จ๊ธฐ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
์บก์ํ(Encapsulation)๋ ๊ฐ์ฒด ๋ด๋ถ์ ์ธ๋ถ ๊ตฌํ์ ๊ฐ์ถ๊ณ , ์ธ๋ถ์๋ ํ์ํ ๋ถ๋ถ๋ง ๊ณต๊ฐํ์ฌ ๊ฐ์ฒด์ ์ผ๊ด์ฑ์ ์ ์งํ๊ณ ์ฝ๋์ ๋ณต์ก์ฑ์ ์ค์ด๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
1๏ธโฃ ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate)์ ๊ตฌ์ฑ ์์.
1๏ธโฃ ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ ๋ฃจํธ(Aggregate Root)
- ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate)์ ์ง์
์ ์ด ๋๋ ๊ฐ์ฒด๋ก, ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate) ์ธ๋ถ์์ ์ ๊ทผํ ์ ์๋ ์ ์ผํ ์ํฐํฐ์
๋๋ค.
- ์ธ๋ถ์์๋ ๋ฃจํธ ์ํฐํฐ๋ฅผ ํตํด์๋ง ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate) ๋ด๋ถ์ ์ ๊ทผํ ์ ์์ต๋๋ค.
2๏ธโฃ ๋ด๋ถ ์ํฐํฐ์ ๊ฐ ๊ฐ์ฒด๋ค.
- ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ ๋ฃจ๋(Aggregate Root)์ ํจ๊ป ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate)๋ฅผ ๊ตฌ์ฑํ๋ ๊ฐ์ฒด๋ค ์
๋๋ค.
- ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ ๋ฃจํธ(Aggregate Root)๊ฐ ์ด๋ค์ ํฌํจํ๊ฑฐ๋ ์ฐธ์กฐํ๋ฉฐ, ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate)์ ์ผ๊ด์ฑ์ ์ฑ ์์ง๋๋ค.
2๏ธโฃ ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate)์ ์์: ์ฃผ๋ฌธ ์์คํ .
- ์ฃผ๋ฌธ ์์คํ
์์ ์ฃผ๋ฌธ(Order)์ด๋ผ๋ ๊ฐ๋
์ ์๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate)๋ก ์ ์ํ ์ ์์ต๋๋ค.
- Order๋ ์ฃผ๋ฌธ ํญ๋ชฉ๋ค(OrderItem)์ ํฌํจํ๋ฉฐ, ์ด๋ค์ ํ ๋จ์๋ก ๋ฌถ์ด ์ฃผ๋ฌธ๊ณผ ๊ด๋ จ๋ ๋ชจ๋ ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํฉ๋๋ค.
```java
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private LocalDateTime orderDate;
private OrderStatus status;@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
private List= items = new ArrayList<>(); public void addItem(OrderItem item) {
items.add(item);
item.setOrder(this);
}public BigDecimal calculateTotalPrice() {
return items.stream()
.map(OrderItem::getTotalPrice)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}public void completeOrder() {
if (items.isEmpty()) {
throw new IllegalStateException(โ์ฃผ๋ฌธ ํญ๋ชฉ์ด ๋น์ด ์์ต๋๋ค.โ);
}
this.status = OrderStatus.COMPLETED;
}
// getter, setter
}
``` - Order๋ ์ฃผ๋ฌธ ํญ๋ชฉ๋ค(OrderItem)์ ํฌํจํ๋ฉฐ, ์ด๋ค์ ํ ๋จ์๋ก ๋ฌถ์ด ์ฃผ๋ฌธ๊ณผ ๊ด๋ จ๋ ๋ชจ๋ ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํฉ๋๋ค.
3๏ธโฃ ์ค๋ช .
- Order๋ ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ ๋ฃจํธ(Aggregate Root)๋ก, ์ฃผ๋ฌธ๊ณผ ๊ด๋ จ๋ ๋ชจ๋ ์ํ์ ๋์์ ์ฑ ์์ง๋๋ค.
- OrderItem ๊ฐ์ฒด๋ Order ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ์ ๋ด๋ถ ๊ตฌ์ฑ ์์๋ก, ์ธ๋ถ์์๋ OrderItem์ ์ง์ ์ ๊ทผํ ์ ์์ต๋๋ค.
- Order๋ ์ฃผ๋ฌธ ํญ๋ชฉ์ ์ถ๊ฐํ๊ณ ์ด ๊ฐ๊ฒฉ์ ๊ณ์ฐํ๋ฉฐ, ์ฃผ๋ฌธ ์๋ฃ ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ๋ ๋ก์ง์ ํฌํจํฉ๋๋ค.
4๏ธโฃ ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate)์ ํน์ง๊ณผ ์์น.
1๏ธโฃ ์ผ๊ด์ฑ ์ ์ง.
- ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate)๋ ํ๋์ ํธ๋์ญ์ ๋ด์์ ํ๋์ ๋จ์๋ก ์ฒ๋ฆฌ๋์ด, ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate) ๋ด๋ถ์ ์ํ์ ๋ฐ์ดํฐ๊ฐ ํญ์ ์ผ๊ด์ฑ์ ์ ์งํฉ๋๋ค.
2๏ธโฃ ๋จ์ผ ์ง์ ์ .
- ์ธ๋ถ์์๋ ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ ๋ฃจํธ(Aggregate Root)๋ฅผ ํตํด์๋ง ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ ๋ด๋ถ ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์์ผ๋ฉฐ, ๋ฃจํธ ์ํฐํฐ๊ฐ ๋ด๋ถ ๊ฐ์ฒด๋ค์ ๋ํ ๊ด๋ฆฌ ๊ถํ์ ๊ฐ์ง๋๋ค.
3๏ธโฃ ๋จ์ผ ์๋ณ์.
- ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate) ์ ์ฒด๋ฅผ ๊ณ ์ ํ๊ฒ ์๋ณํ ์ ์๋ ์๋ณ์๋ ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ ๋ฃจํธ(Aggregate Root)์๋ง ์กด์ฌํ๋ฉฐ, ์์คํ ์ ์ฒด์์ ํด๋น ์๋ณ์๋ก ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate)๋ฅผ ๊ตฌ๋ถํฉ๋๋ค.
5๏ธโฃ ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ(Aggregate) ์ฌ์ฉ์ ์ฅ์ .
1๏ธโฃ ์์ง์ฑ.
- ์ฐ๊ด๋ ๋ฐ์ดํฐ์ ๋ก์ง์ด ํ ๊ณณ์ ๋ชจ์ฌ ๋น์ฆ๋์ค ๋ก์ง์ด ๋ช ํํ๊ฒ ์ ์๋๋ฉฐ, ์ ์ง๋ณด์๊ฐ ์ฉ์ดํด์ง๋๋ค.
2๏ธโฃ ์ผ๊ด์ฑ ๋ณด์ฅ.
- ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ ๋จ์๋ก ํธ๋์ญ์ ์ด ์ฒ๋ฆฌ๋๋ฏ๋ก ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ๋ณด์ฅํ ์ ์์ต๋๋ค.
3๏ธโฃ ์บก์ํ.
- ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ ์ธ๋ถ์์๋ ๋ด๋ถ ๊ฐ์ฒด์ ์ง์ ์ ๊ทผํ ์ ์๊ณ , ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ ๋ฃจํธ๋ฅผ ํตํด์๋ง ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ฏ๋ก ๋ฐ์ดํฐ์ ๋ก์ง์ด ์์ ํ๊ฒ ์บก์ํ๋ฉ๋๋ค.
5๏ธโฃ ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ์ ์์ ์ํฉ.
- ์ฃผ๋ฌธ(Order) ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ : ์ฃผ๋ฌธ ํญ๋ชฉ(OrderItem)๊ณผ ๊ฒฐ์ ์ ๋ณด(PaymentInfor) ๋ฑ์ ํฌํจํ์ฌ, ํ๋์ ์ฃผ๋ฌธ ๋จ์๋ก ๋ฌถ์.
- ์ฌ์ฉ์(User) ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ : ์ฌ์ฉ์ ์ ๋ณด์ ์ฌ์ฉ์ ํ๋กํ(Profile), ์ฐ๋ฝ์ฒ(Contact) ๋ฑ์ ํฌํจํ์ฌ ์ฌ์ฉ์์ ๊ด๋ จ๋ ๋ชจ๋ ์ ๋ณด๋ฅผ ํ๋๋ก ๋ฌถ์.
6๏ธโฃ ์์ฝ.
- ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ๋ ๋ฐ์ ํ๊ฒ ์ฐ๊ด๋ ๊ฐ์ฒด๋ค์ ํ๋์ ์ผ๊ด์ฑ ์๋ ๋ณ๊ฒฝ ๋จ์๋ก ๋ฌถ์ด ๊ด๋ฆฌํ๋ ๊ฐ๋ ์ ๋๋ค.
- ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ ๋ฃจํธ๋ฅผ ํตํด์๋ง ์ ๊ทผ์ด ๊ฐ๋ฅํ๋๋ก ์บก์ํํ์ฌ ๋ฐ์ดํฐ์ ๋น์ฆ๋์ค ๋ก์ง์ ์์ง์ฑ๊ณผ ์ผ๊ด์ฑ์ ์ ์งํ๋ฉฐ, ๊ฐ์ฒด ์งํฅ์ ์ธ ๋ฐฉ์์ผ๋ก ์์คํ ์ ๋ชจ๋ธ๋งํ ์ ์๊ฒ ํฉ๋๋ค.