JPA 강의를 수강 중 강사님은 엔티티 자체가 해결할 수 있는 것은 엔티티 안에 비즈니스 로직을 넣는 것을 추천하셨다.
그러나 각 패턴의 장단점이 있기때문에 상황에 맞게 적절한 방법을 선택하는 것이 중요하다고 하셨다.
관련 강의 질문
그럼 두 패턴의 정의와 패턴의 장단점을 정리하고, 어떤 상황에 어떤 패턴을 적용해야 하는지 대해 정리해보겠다.
엔티티 자체가 비즈니스 로직을 포함하고 이를 통해 상태를 변경하는 방식이다. 이 패턴은 주로 도메인 주도 설계(DDD)에서 사용된다.
장점
information expert pattern
책임을 수행할 정보를 알고 있는 객체에게 책임을 할당하는 것이다.
이 패턴을 따르면 정보와 행동을 최대한 가까운 곳에 위치시키기 때문에 캡슐화를 유지할 수 있다.
단점
예시
@Entity
@Getter
@Setter
@Table(name = "orders")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Order {
...
public void cancel() {
if (delivery.getStatus() == DeliveryStatus.COMP) {
throw new IllegalStateException("이미 배송완료된 상품은 취소가 불가능합니다.");
}
this.setStatus(OrderStatus.CANCEL);
for (OrderItem orderItem : orderItems) {
orderItem.cancel();
}
}
}
}
→ 주문 취소 로직 같은 경우 엔티티 내에서 직접 수행하고, 서비스 계층에서는 이를 호출하는 역할만 한다.
대부분의 비즈니스 로직을 서비스 계층에서 처리하고 엔티티는 단순히 getter, setter 정도만 제공한다.
장점
단점
예시
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class OrderService {
@Transactional
public void cancelOrder(Long orderId) {
Order order = orderRepository.findOne(orderId);
if (order.getStatus() == OrderStatus.CANCEL) {
throw new IllegalStateException("이미 취소된 주문입니다.");
}
order.setStatus(OrderStatus.CANCEL);
orderRepository.save(order);
}
}
→ 서비스 계층에서는 엔티티에 getter를 사용하여 데이터를 가져와서 비교하고 직접 엔티티의 상태를 변경한다.
참고
실전! 스프링 부트와 JPA 활용1,
Information Expert Pattern,
Transaction Script Pattern