๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Programming Books/DDD START!

Chapter 2. ์•„ํ‚คํ…์ฒ˜ ๊ฐœ์š”

by IamBeau 2022. 8. 15.

์•„ํ‚คํ…์ฒ˜

๐Ÿ‘€  ์•„ํ‚คํ…์ฒ˜์˜ ์ „ํ˜•์ „์ต ์˜์—ญ

- ํ‘œํ˜„, ์‘์šฉ, ๋„๋ฉ”์ธ, ์ธํ”„๋ผ์ŠคํŠธ๋Ÿญ์ฒ˜

ํ‘œํ˜„ ์˜์—ญ

  • ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์„ ๋ฐ›์•„ ์‘์šฉ ์˜์—ญ์— ์ „๋‹ฌํ•˜๊ณ  ์‘์šฉ ์˜์—ญ์˜ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์‹œ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ฃผ๋Š” ์—ญํ• 
  • ๋Œ€ํ‘œ์ ์ธ ํ‘œํ˜„ ์˜์—ญ์˜ ์‚ฌ์šฉ์ž๋Š” ์›น ๋ธŒ๋ผ์šฐ์ € ์ด์šฉ์ž, REST API ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์™ธ๋ถ€ ์‹œ์Šคํ…œ ๋“ฑ 

์‘์šฉ ์˜์—ญ

  • ์‹œ์Šคํ…œ์ด ์‚ฌ์šฉ์ž์—๊ฒŒ ์ œ๊ณตํ•ด์•ผ ํ•  ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ณ , ๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ ๋„๋ฉ”์ธ ์˜์—ญ์˜ ๋„๋ฉ”์ธ ๋ชจ๋ธ์„ ์‚ฌ์šฉ
  • ๋กœ์ง์„ ์ง์ ‘ ์ˆ˜ํ–‰ํ•˜๊ธฐ๋ณด๋‹ค๋Š” ๋„๋ฉ”์ธ ๋ชจ๋ธ์— ๋กœ์ง ์ˆ˜ํ–‰์„ ์œ„์ž„
public class CancelOrderService {

   @Transactional
    public void cancelOrder(String orderId) {
    	Order order = findOrderById(orderId);
        if (order == null) throw new OrderNotFoundException(orderId);
        order.cancel(); // ๋„๋ฉ”์ธ ๋ชจ๋ธ ๋‚ด๋ถ€์— ์žˆ๋Š” ์ฃผ๋ฌธ ์ทจ์†Œ ๋กœ์ง์— ํ•ด๋‹นํ•˜๋Š” cancel() ์‚ฌ์šฉ
    }
    
}

 

๋„๋ฉ”์ธ ์˜์—ญ

  • ๋„๋ฉ”์ธ ์˜์—ญ์€ ๋„๋ฉ”์ธ ๋ชจ๋ธ์„ ๊ตฌํ˜„ํ•˜๊ณ , ๋„๋ฉ”์ธ์˜ ํ•ต์‹ฌ ๋กœ์ง์„ ๊ตฌํ˜„
    • ex) ๋ฐฐ์†ก์ง€ ๋ณ€๊ฒฝ, ๊ฒฐ์ œ ์™„๋ฃŒ, ์ฃผ๋ฌธ ์ด์•ก ๊ณ„์‚ฐ
public class Order {
   private OrderStatus status;

   public void cancel() {
      this.status = OrderStatus.CANCELED;
   }
   
}

public enum OrderStatus {
   ...
   CANCELED,
   ...
}

 

์ธํ”„๋ผ์ŠคํŠธ๋Ÿญ์ฒ˜ ์˜์—ญ

  • RDBMS, MongoDB, HBase ๋“ฑ ์—ฐ๋™์„ ์ฒ˜๋ฆฌ
  • Message Queue์— message ๋ฅผ ์ „์†ก / ์ˆ˜์‹ 
  • SMTP ๋ฉ”์ผ ๋ฐœ์†ก 

 

๊ณ„์ธต ๊ตฌ์กฐ ์•„ํ‚คํ…์ฒ˜

๐Ÿ‘€  ๋„ค ์˜์—ญ์„ ๊ตฌ์„ฑํ•  ๋•Œ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ์•„ํ‚คํ…์ฒ˜๊ฐ€ ์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์€ ๊ณ„์ธต ๊ตฌ์กฐ

  • ๊ณ„์ธต ๊ตฌ์กฐ๋Š” ์ƒ์œ„ ๊ณ„์ธต์—์„œ ํ•˜์œ„ ๊ณ„์ธต์œผ๋กœ์˜ ์˜์กด๋งŒ ์กด์žฌ
    • ex) ์‘์šฉ ๊ณ„์ธต์ด ๋„๋ฉ”์ธ ๊ณ„์ธต์—๋Š” ์˜์กดํ•˜์ง€๋งŒ, ๋„๋ฉ”์ธ ๊ณ„์ธต์ด ์‘์šฉ ๊ณ„์ธต์— ์˜์กดํ•˜์ง€๋Š” ์•Š์Œ
  • ๊ตฌํ˜„์˜ ํŽธ๋ฆฌํ•จ์„ ์œ„ํ•ด ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ์œ ์—ฐํ•˜๊ฒŒ๋„ ์ ์šฉ ํ•  ์ˆ˜ ์žˆ์Œ
    • ex) ์‘์šฉ ๊ณ„์ธต์ด ๋„๋ฉ”์ธ ๊ณ„์ธต์—๋„ ์˜์กดํ•˜๊ณ , ์™ธ๋ถ€ ์‹œ์Šคํ…œ๊ณผ์˜ ์—ฐ๋™์„ ์œ„ํ•ด ์ธํ”„๋ผ์ŠคํŠธ๋Ÿญ์ฒ˜ ๊ณ„์ธต์—๋„ ์˜์กดํ•˜๊ธฐ๋„ ํ•จ

๐Ÿ“• Rule Engine ์ด๋ž€ ?
- ๋ฃฐ ์—”์ง„์„ ๋กค(Rule; ๊ทœ์น™, ์ฆ‰ ๋กœ์ง)์„ ๋ณ„๋„๋กœ ์ €์žฅํ•ด๋‘๊ณ  ํ”„๋กœ๊ทธ๋žจ์—์„œ ๋ฃฐ์„ ๊ฐ€์ ธ๋‹ค ์“ธ ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณต

Business Logic ์ด ๋งค์šฐ ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒฝ์šฐ, ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ˆ˜์ •์ด ๋งค์šฐ ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋ฐœ์ƒ
๋”ฐ๋ผ์„œ, ํ•ด๋‹น ๋กœ์ง์„ ๋ฃฐ ์—”์ง„์œผ๋กœ ์˜ฎ๊ฒจ๊ฐ€๊ณ , ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ๋กค ์—”์ง„์„ ํ†ตํ•ด์„œ ๋ฃฐ(๋กœ์ง)์„ ์‹คํ–‰ํ•˜๋„๋ก ์ฒ˜๋ฆฌ

ex) ๋งค๋…„ ๊ณ„์†ํ•ด์„œ ๋ณ€ํ•˜๋Š” ์„ธ์œจ์— ๋”ฐ๋ฅธ ์„ธ๊ธˆ ๊ณ„์‚ฐ ๋กœ์ง

 

DIP

๐Ÿ‘€  DIP ๋ž€?

- ์˜์กด ์—ญ์ „ ์›์น™(Dependency Inversion Principle) : ๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ์€ ์ €์ˆ˜์ค€ ๋ชจ๋“ˆ์˜ ๊ตฌํ˜„์— ์˜์กดํ•ด์„œ๋Š” ์•ˆ ๋˜๋ฉฐ, ์ €์ˆ˜์ค€ ๋ชจ๋“ˆ์ด ๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ์—์„œ ์ •์˜ํ•œ ์ถ”์ƒ ํƒ€์ž…์— ์˜์กดํ•ด์•ผ ํ•จ (์ž์‹ ๋ณด๋‹ค ๋ณ€ํ•˜๊ธฐ ์‰ฌ์šด ๊ฒƒ์— ์˜์กดํ•˜์ง€ ๋งˆ๋ผ)

 

  • Ex) DIP ๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š์€ ์ฃผ๋ฌธ ์‹œ ํ• ์ธ์œจ ์ ์šฉ ์ฝ”๋“œ
class CalculateDiscountService { 
    private DroolsRuleEngine ruleEngine = new DroolsRuleEngine();

    public Money calculateDiscount(List<OrderLine> orderLines, String customerId) {
        Customer customer = findCustomer(customerId);

        // ์ดˆ๊ธฐ ๋ˆ
        MutableMoney money = new MutableMoney(0);
        
        // DroolsRulsEngine ์‚ฌ์šฉ์„ ์œ„ํ•œ ์กฐ๊ฑด ์ถ”๊ฐ€
        List<?> conditions = Arrays.asList(customer, money);
        conditions.addAll(orderLines);

        // DroolsRulsEngine์„ ์ด์šฉํ•ด ํ• ์ธ์œจ ์ ์šฉ
        ruleEngine.evaluate("discountCalculation", conditions);
        
        // ํ• ์ธ์œจ ์ ์šฉ ๋œ ๋ˆ์„ ๋ถˆ๋ณ€์œผ๋กœ ๋ณ€๊ฒฝ
        return money.toImmutableMoney();
    }
    
}

 

์œ„ ์ฝ”๋“œ๋Š” 2๊ฐ€์ง€ ๋ฌธ์ œ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Œ

  • ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์–ด๋ ค์›€
    • DroolsRuleEngine์ด ์™„๋ฒฝํ•˜๊ฒŒ ๋™์ž‘ํ•ด์•ผ๋งŒ CalculateDiscountService๋ฅผ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ
  • ๊ตฌํ˜„ ๋ฐฉ์‹์„ ๋ณ€๊ฒฝํ•˜๊ธฐ ์–ด๋ ค์›€
    • DroolsRuleEngine์ด ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์—”์ง„์„ ์‚ฌ์šฉํ•˜๋„๋ก ๋ณ€๊ฒฝํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด ๋งŽ์€ ๋ถ€๋ถ„์ด ๋ณ€๊ฒฝ๋˜์–ด์•ผํ•จ

 

  • Ex) DIP ๊ฐ€ ์ ์šฉ๋œ ์ฃผ๋ฌธ ์‹œ ํ• ์ธ์œจ ์ ์šฉ ์ฝ”๋“œ
interface RuleDiscounter {
    public Money applyRules(Customer customer, List<OrderLine> orderLines);
}

class CalculateDiscountService { 
    private RuleDiscounter ruleDiscounter;

    public CalculateDiscountService(RuleDiscounter ruleDiscounter) {
        this.ruleDiscounter = ruleDiscounter;
    }

    public Money calculateDiscount(List<OrderLine> orderLines, String customerId) {
        Customer customer = findCustomer(customerId);
        return ruleDiscounter.applyRules(customer, orderLines);
    }
}

class DroolsRuleDiscounter implements RuleDiscounter {

    @Override
    public Money calculateDiscount(List<OrderLine> orderLines, String customerId) {
       ...
    }
    
}

์ €์ˆ˜์ค€ ๋ชจ๋“ˆ์ด ๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ์— ์˜์กดํ•˜๋„๋ก ๋ณ€๊ฒฝ

  • CalculateDiscountService ์ž…์žฅ์—์„œ๋Š” ํ• ์ธ์œจ ๋ฃฐ ์ ์šฉ์„ ์–ด๋–ค ์—”์ง„์„ ํ†ตํ•ด ๊ตฌํ˜„ํ–ˆ๋Š”์ง€ ์ค‘์š”ํ•˜์ง€ ์•Š์Œ
    • ๊ณ ๊ฐ ์ •๋ณด์™€ ๊ตฌ๋งค ์ •๋ณด์— ํ• ์ธ์œจ ๋ฃฐ์„ ์ ์šฉํ•ด์„œ ํ• ์ธ ๊ธˆ์•ก์„ ๊ตฌํ•œ๋‹ค๋Š” ์‚ฌ์‹ค๋งŒ ์ค‘์š”
  • CalculateDiscountService ๋Š” ๋” ์ด์ƒ ๊ตฌํ˜„ ๊ธฐ์ˆ ์ธ DroolsRuleDiscounter ์— ์˜์กดํ•˜์ง€ ์•Š๊ณ  ์ถ”์ƒํ™”ํ•œ ๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ์ธ RuleDiscounter ์— ์˜์กด

 

์œ„ 2๊ฐ€์ง€ ๋ฌธ์ œ๋„ ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์žˆ์Œ

  • ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์‰ฌ์›€
    • ํŠน์ • ํด๋ž˜์Šค๊ฐ€ ์•„๋‹ˆ๋ผ ์ธํ„ฐํŽ˜์ด์Šค์— ์˜์กดํ•˜๋ฏ€๋กœ mockito๋ฅผ ์‚ฌ์šฉํ•œ stub ๋“ฑ์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ง์ ‘ ๊ตฌํ˜„์ฒด๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ณ ๋„ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค
public class CalculateDiscountServiceTest {

   @Test(expected = NoCustomerException.class);
   public void noCustomer_thenExceptionShouldBeThorwn() {
      // ํ…Œ์ŠคํŠธ ๋ชฉ์ ์˜ ๋Œ€์šฉ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ
      CustomerRepository stubRepo = mock(CustomerRepository.class);
      when(stubRepo.findById("noCustomerId")).thenReturn(null);
      
      RuleDiscounter stubRule = (customer, lines) -> null;
      
      // ํ…Œ์ŠคํŠธ ๋ชฉ์ ์˜ ๋Œ€์šฉ ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…๋ฐ›์•„ ํ…Œ์ŠคํŠธ ์ง„ํ–‰
      CalculateDiscountService calcDiscountService = new CalculateDiscountService(stubRepo, stubRule);
      calcDiscountService.calculateDiscount(someLines, "noCustomerId");
   }

}

 

  • ๊ตฌํ˜„ ๋ฐฉ์‹์„ ๋ณ€๊ฒฝํ•˜๊ธฐ ์‰ฌ์›€
    • ์ €์ˆ˜์ค€ ๋ชจ๋“ˆ์— ๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋˜์–ด ์žˆ๋Š” ๊ตฌ์กฐ๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ตฌํ˜„ ๊ธฐ์ˆ ์„ ๋ณ€๊ฒฝํ•˜๋”๋ผ๋„ CalculateDiscountService๋ฅผ ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Œ
// ์‚ฌ์šฉํ•  ์ €์ˆ˜์ค€ ๊ฐ์ฒด ์ƒ์„ฑ (Drool ์—”์ง„ ์‚ฌ์šฉ)
RuleDiscounter ruleDiscounter = new DroolsRuleDiscounter();

// ์‚ฌ์šฉํ•  ์ €์ˆ˜์ค€ ๊ฐ์ฒด ๋ณ€๊ฒฝ (๋˜๋‹ค๋ฅธ ์ €์ˆ˜์ค€ ๋ชจ๋“ˆ ์‚ฌ์šฉ)
RuleDiscounter ruleDiscounter = new SimpleRuleDiscounter();

// ์ƒ์„ฑ์ž ๋ฐฉ์‹์œผ๋กœ ์ฃผ์ž…ํ•˜๊ณ , ์ €์ˆ˜์ค€ ๋ชจ๋“ˆ์„ ์œ„ ๊ฐ™์ด ๋ณ€๊ฒฝํ•˜๋”๋ผ๋„ ๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ์€ ์ˆ˜์ •ํ•  ํ•„์š” ์—†์Œ
CalculateDiscountService discountService = new CalculateDiscountService(ruleDiscounter);

 

๋„๋ฉ”์ธ ์˜์—ญ์˜ ์ฃผ์š” ๊ตฌ์„ฑ์š”์†Œ

  • ์—”ํ‹ฐํ‹ฐ
    • ๊ณ ์œ ์˜ ์‹๋ณ„์ž๋ฅผ ๊ฐ€์ง€๊ณ  ์ž์‹ ์˜ ๋ผ์ดํ”„ ์‚ฌ์ดํด์„ ๊ฐ–๋Š” ๊ฐ์ฒด
    • ๋ฐ์ดํ„ฐ์™€ ๋ฐ์ดํ„ฐ์™€ ๊ด€๋ จ๋œ ๊ธฐ๋Šฅ์„ ํ•จ๊ป˜ ์ œ๊ณต
    • ex) ์ฃผ๋ฌธ(Order), ํšŒ์›(Member), ์ƒํ’ˆ(Product)
    • ๋„๋ฉ”์ธ ๋ชจ๋ธ์˜ ์—”ํ‹ฐํ‹ฐ์™€ DB ๋ชจ๋ธ์˜ ์—”ํ‹ฐํ‹ฐ๋Š” ๋‹ค๋ฆ„
      • RDBMS๋Š” ๋ฐธ๋ฅ˜๋ฅผ ์ œ๋Œ€๋กœ ํ‘œํ˜„ํ•˜๊ธฐ ํž˜๋“ฌ
      • ORDER_NAME, ORDER_EMAIL ํ•„๋“œ๋กœ ํ‘œ์‹œํ•˜๊ฑฐ๋‚˜ ๋˜๋Š” ORDER_ORDERER ํ…Œ์ด๋ธ”๋กœ ํ‘œ์‹œํ•˜๋”๋ผ๋„ ๋”ฑํžˆ ๋ฐธ๋ฅ˜ ํƒ€์ž…์˜ ์˜๋ฏธ๊ฐ€ ๋“œ๋Ÿฌ๋‚˜์ง€ ์•Š์Œ
  • ๋ฐธ๋ฅ˜
    • ๊ณ ์œ ์˜ ์‹๋ณ„์ž๋ฅผ ๊ฐ–์ง€ ์•Š๊ณ  ์ฃผ๋กœ ๋„๋ฉ”์ธ ๊ฐ์ฒด์˜ ์†์„ฑ์„ ํ‘œํ˜„ํ•  ๋–„ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด
    • ์—”ํ‹ฐํ‹ฐ์˜ ์†์„ฑ์œผ๋กœ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๋‹ค๋ฅธ ๋ฐธ๋ฅ˜ ํƒ€์ž…์˜ ์†์„ฑ์œผ๋กœ๋„ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Œ
  • ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ
    • ๊ด€๋ จ๋œ ์—”ํ‹ฐํ‹ฐ์™€ ๋ฐธ๋ฅ˜ ๊ฐ์ฒด๋ฅผ ๊ฐœ๋…์ ์œผ๋กœ ํ•˜๋‚˜๋กœ ๋ฌถ์€ ๊ฒƒ
    • ๋„๋ฉ”์ธ์ด ์ปค์งˆ์ˆ˜๋ก ๊ฐœ๋ฐœํ•  ๋„๋ฉ”์ธ ๋ชจ๋ธ๋„ ์ปค์ง€๊ฒŒ ๋˜๊ณ , ๋งŽ์€ ์—”ํ‹ฐํ‹ฐ์™€ ๋ฒจ๋ฅ˜๊ฐ€ ์ƒ๊ธฐ๋ฉด์„œ ๋ชจ๋ธ์ด ์ ์  ๋” ๋ณต์žกํ•ด์ง
      -> ๊ฐœ๋ฐœ์ž๊ฐ€ ์ „์ฒด ๊ตฌ์กฐ๊ฐ€ ์•„๋‹Œ ํ•œ๊ฐœ ์—”ํ‹ฐํ‹ฐ์™€ ๋ฒจ๋ฅ˜์— ์ง‘์ค‘ํ•˜๊ฒŒ ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋ฐœ์ƒ
    • ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋ฅผ ํ†ตํ•ด ๋„๋ฉ”์ธ ๋ชจ๋ธ์„ ๊ฐœ๋ณ„ ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ์ƒ์œ„ ์ˆ˜์ค€์—์„œ ๋ชจ๋ธ์„ ๋ณผ ์ˆ˜ ์žˆ์–ด์•ผ ์ „์ฒด ๋ชจ๋ธ๊ณผ ๊ฐœ๋ณ„ ๋ชจ๋ธ์„ ์ดํ•ดํ•˜๋Š”๋ฐ ๋„์›€์ด ๋จ
    • ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋Š” ๊ตฐ์ง‘์— ์†ํ•œ ๊ฐ์ฒด๋“ค์„ ๊ด€๋ฆฌํ•˜๋Š” ๋ฃจํŠธ ์—”ํ‹ฐํ‹ฐ๋ฅผ ๊ฐ€์ง
    • ๋ฃจํŠธ ์—”ํ‹ฐํ‹ฐ๋Š” ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์— ์†ํ•ด ์žˆ๋Š” ์—”ํ‹ฐํ‹ฐ์™€ ๋ฐธ๋ฅ˜ ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๊ฐ€ ๊ตฌํ˜„ํ•ด์•ผ ํ•  ๊ธฐ๋Šฅ์„ ์ œ๊ณต
    • ex) Order ๋ฃจํŠธ ์—”ํ‹ฐํ‹ฐ, OrderLine ๋ฐธ๋ฅ˜, Orderer ๋ฐธ๋ฅ˜ -> ์ฃผ๋ฌธ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ
  • ๋ฆฌํฌ์ง€ํ„ฐ๋ฆฌ
    • ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ์ง€์†์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ ค๋ฉด RDBMS ๊ฐ™์€ ๋ฌผ๋ฆฌ์  ์ €์žฅ์†Œ์— ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ๋ณด๊ด€ํ•ด์•ผ ํ•˜๊ณ , ์ด๋ฅผ ์œ„ํ•œ ๋„๋ฉ”์ธ ๋ชจ๋ธ
    • ๋„๋ฉ”์ธ ๋ชจ๋ธ์˜ ์˜์†์„ฑ์„ ์ฒ˜๋ฆฌํ•จ
    • ๋ฆฌํฌ์ง€ํ„ฐ๋ฆฌ๋Š” ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ์˜์†ํ™”ํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ์ถ”์ƒํ™” ํ•œ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ์— ์†ํ•˜๊ณ , ์‹ค์ œ ๊ตฌํ˜„ ํด๋ž˜์Šค๋Š” ์ธํ”„๋ผ์ŠคํŠธ๋Ÿญ์ณ ์˜์—ญ์— ์†ํ•จ
    • ์‘์šฉ ์„œ๋น„์Šค๋Š” ํ•„์š”ํ•œ ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ๊ตฌํ•˜๊ฑฐ๋‚˜ ์ €์žฅํ•  ๋•Œ ๋ฆฌํฌ์ง€ํ„ฐ๋ฆฌ๋ฅผ ์ด์šฉ
  • ๋„๋ฉ”์ธ ์„œ๋น„์Šค
    • ํŠน์ • ์—”ํ‹ฐํ‹ฐ์— ์†ํ•˜์ง€ ์•Š์€ ๋„๋ฉ”์ธ ๋กœ์ง์„ ์ œ๊ณตํ•จ
    • ๋„๋ฉ”์ธ ๋กœ์ง์ด ์—ฌ๋Ÿฌ ์—”ํ‹ฐํ‹ฐ์™€ ๋ฒจ๋ฅ˜๋ฅผ ํ•„์š”๋กœ ํ•  ๊ฒฝ์šฐ ์—ฌ๊ธฐ์—์„œ ๋กœ์ง์„ ๊ตฌํ˜„ํ•œ๋‹ค
    • ex) "ํ• ์ธ ๊ธˆ์•ก ๊ณ„์‚ฐ" ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ƒํ’ˆ, ์ฟ ํฐ, ํšŒ์› ๋“ฑ๊ธ‰, ๊ตฌ๋งค ๊ธˆ์•ก ๋“ฑ ๋‹ค์–‘ํ•œ ์—”ํ‹ฐํ‹ฐ์™€ ๋ฐธ๋ฅ˜๊ฐ€ ํ•„์š”

 

๋ชจ๋“ˆ ๊ตฌ์„ฑ

  • ๊ธฐ๋ณธ์ ์œผ๋กœ ์šฐ๋ฆฌ๋Š” ํ•ญ์ƒ ์•„ํ‚คํ…์ณ๊ฐ€ ๊ฐ ์˜์—ญ์ด ๋ณ„๋„ ํŒจํ‚ค์ง€์— ์œ„์น˜ํ•˜๋Š” ํ˜•ํƒœ๋กœ ๊ตฌ์„ฑ
com.myshop.interface
com.myshop.application
com.myshop.domain
com.myshop.infrastructure

 

  • ๋„๋ฉ”์ธ์ด ํฌ๋ฉด ํ•˜์œ„ ๋„๋ฉ”์ธ๋งˆ๋‹ค ๋ณ„๋„ ํŒจํ‚ค์ง€๋ฅผ ๊ตฌ์„ฑ
// ํšŒ์› ๋„๋ฉ”์ธ
com.myshop.member.interface
com.myshop.member.application
com.myshop.member.domain
com.myshop.member.infrastructure

// ์ฃผ๋ฌธ ๋„๋ฉ”์ธ
com.myshop.order.interface
com.myshop.order.application
com.myshop.order.domain
com.myshop.order.infrastructureโ€‹

 

  • ๋„๋ฉ”์ธ ๋‚ด๋ถ€์—์„œ ์„œ๋กœ๋‹ค๋ฅธ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋กœ ๋‚˜๋ˆ ์ง€๋Š” ๊ฒฝ์šฐ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Œ
com.myshop.order.interface
com.myshop.order.application
com.myshop.order.domain.product
com.myshop.order.domain.category
com.myshop.order.infrastructure

 

  • ๋งŒ์•ฝ ๋„๋ฉ”์ธ ์„œ๋น„์Šค ๊ณ„์ธต์ด ๋”ฐ๋กœ ์žˆ์œผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚˜๋‰  ์ˆ˜ ์žˆ์Œ
com.myshop.order.domain.product
com.myshop.order.domain.category
com.myshop.order.domain.service


๋ชจ๋“ˆ ๊ตฌ์„ฑ์— ์ •๋‹ต์€ ์—†์ง€๋งŒ ๊ฐ€๋Šฅํ•˜๋ฉด ํ•œ ํŒจํ‚ค์ง€๋‚ด์— 10๊ฐœ ๋ฏธ๋งŒ์œผ๋กœ ๋„๋ฉ”์ธ ํƒ€์ž… ๊ฐœ์ˆ˜๋ฅผ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด GOOD

 

 


์ตœ๋ฒ”๊ท  ์ž‘๊ฐ€๋‹˜์˜ DDD START! 2์žฅ์„ ์š”์•ฝํ–ˆ์Šต๋‹ˆ๋‹ค.

'Programming Books > DDD START!' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Chapter 1. ๋„๋ฉ”์ธ ๋ชจ๋ธ ์‹œ์ž‘  (0) 2022.08.14

๋Œ“๊ธ€