Home > Spring > ๐Ÿƒ[Spring] ์• ๊ทธ๋ฆฌ๊ฒŒ์ดํŠธ(Aggregate)๋ž€ ๋ฌด์—‡์ผ๊นŒ์š”?

๐Ÿƒ[Spring] ์• ๊ทธ๋ฆฌ๊ฒŒ์ดํŠธ(Aggregate)๋ž€ ๋ฌด์—‡์ผ๊นŒ์š”?
Spring Framework

๐Ÿƒ[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
    }
    ```

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๏ธโƒฃ ์š”์•ฝ.

  • ์• ๊ทธ๋ฆฌ๊ฒŒ์ดํŠธ๋Š” ๋ฐ€์ ‘ํ•˜๊ฒŒ ์—ฐ๊ด€๋œ ๊ฐ์ฒด๋“ค์„ ํ•˜๋‚˜์˜ ์ผ๊ด€์„ฑ ์žˆ๋Š” ๋ณ€๊ฒฝ ๋‹จ์œ„๋กœ ๋ฌถ์–ด ๊ด€๋ฆฌํ•˜๋Š” ๊ฐœ๋…์ž…๋‹ˆ๋‹ค.
  • ์• ๊ทธ๋ฆฌ๊ฒŒ์ดํŠธ ๋ฃจํŠธ๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ์บก์Šํ™”ํ•˜์—ฌ ๋ฐ์ดํ„ฐ์™€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์˜ ์‘์ง‘์„ฑ๊ณผ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๋ฉฐ, ๊ฐ์ฒด ์ง€ํ–ฅ์ ์ธ ๋ฐฉ์‹์œผ๋กœ ์‹œ์Šคํ…œ์„ ๋ชจ๋ธ๋งํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.