π[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οΈβ£ μμ½.
- μ 그리κ²μ΄νΈλ λ°μ νκ² μ°κ΄λ κ°μ²΄λ€μ νλμ μΌκ΄μ± μλ λ³κ²½ λ¨μλ‘ λ¬Άμ΄ κ΄λ¦¬νλ κ°λ μ λλ€.
- μ 그리κ²μ΄νΈ 루νΈλ₯Ό ν΅ν΄μλ§ μ κ·Όμ΄ κ°λ₯νλλ‘ μΊ‘μννμ¬ λ°μ΄ν°μ λΉμ¦λμ€ λ‘μ§μ μμ§μ±κ³Ό μΌκ΄μ±μ μ μ§νλ©°, κ°μ²΄ μ§ν₯μ μΈ λ°©μμΌλ‘ μμ€ν μ λͺ¨λΈλ§ν μ μκ² ν©λλ€.