상품
주문
할인
회원
실제 결제 금액을 계산해야하는 주체를
주문
Aggregate로 할당하는 것보다,따로 실제 결제 금액을 계산하는 별도의
도메인 서비스
를 구현하는 것이 좋다.
public class DiscountCalculationService {
public Money calculateDiscountAmounts(
List<Coupon> coupons,
MemberGrade grade
) {
Money couponDiscount = calculateDiscount(coupons);
Money membershipDiscount = calculateDiscount(grade);
return couponDiscount + membershipDiscount;
}
public Money calculateDiscount(List<Coupon> coupons) {
// ...
}
public Money calculateDiscount(MemberGrade grade) {
// ...
}
}
public class Order {
public void calculateAmounts(
DiscountCalculationService discountCalculationService,
MemberGrade grade
) {
Money totalAmounts = getTotalAmounts();
Money discountAmounts = discountCalculationService.calculateDiscountAmounts(this.coupons,
grade);
this.paymentAmounts = totalAmounts - discountAmounts;
}
}
public class OrderService {
private final DiscountCalculationService discountCalculationService;
@Transactional
public OrderNo takeOrder(OrderRequest req) {
Order order = createOrder(orderRequest);
orderRepository.save(order);
return order.getOrderNo();
}
private Order createOrder(OrderRequest req) {
Member member = memberRepository.findById(req.getOrdererId());
Order order = new Order(/* ... */);
order.calculateAmounts(this.discountCalculationService, member.getGrade());
return order;
}
}
public class TransferService {
public void transfer(Account fromAccount, Account toAccount, Money amounts) {
fromAccount.withDraw(amounts);
toAccount.credit(amounts);
}
}