이번 포스팅에서는 Domain Layer를 이용해서 비즈니스 로직을 처리해야 하는 이유와 간단한 예제를 공부한다.
우선 Spring의 Web 계층구조에 대해 살펴보자.
@Service
에 사용되는 서비스 영역이다.나는 비즈니스 로직은 Servier Layer
에서 처리되어야 한다고 배웠다.
하지만 이 책에서는 Domain Layer
에서 비즈니스 로직이 처리되어야 한다고 얘기하고 있다.
왜 Service Layer가 아닌 Domain Layer에서 비즈니스 로직을 처리해야 한다고 말하는지 두 방식을 예제코드로 비교해보자
@Transactional
public Order cancelOrder(int orderId) {
// 1)
OrderDto order = orderDao.selectOrders(orderId);
BiliingDto billing = billingDao.selectBilling(orderId);
DeliveryDto delivery = deliveryDao.selectDelivery(orderId);
// 2)
String deliveryStatus = delivery.getStatus();
// 3)
if("IN_PROGRESS".equals(deliveryStatus)) {
delivery.setStatus("CANCEL");
deliveryDao.update(delivery);
}
// 4)
order.setStatus("CANCEL");
orderDao.update(order);
billing.setStatus("CANCEL");
deliveryDao.update(billing);
return order;
}
Service Layer에서 비즈니스 로직을 처리하는 예제코드이다.
모든 로직이 서비스 클래스 내부에서 처리된다.
그러다 보니 서비스 계층이 무의미하며, 객체는 단순히 데이터 덩어리 역할만 하게된다.
이 비즈니스 로직을 도메인 모델에서 수행하도록 해보자
@Transactional
public Order cancelOrder(int orderId) {
// 1)
Orders order = ordersRepository.findById(orderId);
Billing billing = billingRepository.findByOrderId(orderId);
Delivery delivery = deliveryRepository.findByOrderId(orderId);
// 2-3)
delivery.cancel();
// 4)
order.cancel();
billing.cancel();
return order;
}
취소 이벤트를 처리하는 로직은 각각의 Domain Model에서 수행하고 있다.
Service Layer에서는 트랜잭션과 도메인 간의 순서만을 보장한다.
가장 큰 차이점은 객체를 얼마나 활용했는가라고 생각한다.
Service Layer에서 로직을 처리할 때는 객체는 쿼리 결과를 가지고 있는 상자정도로 사용되는 것 같다.
하지만 Domain Model에서 로직을 처리할 때는 각각의 객체들이 자신의 이벤트를 처리하는 것을 볼 수 있다.
즉, Domain Model에서 로직을 처리하는 방식이 객체를 더욱 활용하는 방법이라는 것이다.
하지만 JPA가 아닌 MyBatis를 사용하는 경우에는 Domain Model에서 비즈니스 로직을 처리하기는 방법을 사용하는 것이 쉽지 않아보인다.
결론적으로 두 가지 방법 모두 좋지만 객체지향관점에서는 Domain Model에서 비즈니스 로직을 처리하는 것이 좋다고 생각한다.