본문 바로가기
Backend

[실전! 스프링부트와 JPA활용] 주문 서비스 개발 / 도메인 모델 패턴 vs 트랜잭션 스크립트 패턴

by 햣둘 2025. 4. 7.

주문 서비스 코드

주문 서비스는 주문 엔티티와 주문상품 엔티티의 비즈니스를 "활용"해서 주문, 주문취소, 주문내역 검색 기능을 제공한다.

package jpabook.jpashop.service;

import jpabook.jpashop.domain.Delivery;
import jpabook.jpashop.domain.Member;
import jpabook.jpashop.domain.Order;
import jpabook.jpashop.domain.OrderItem;
import jpabook.jpashop.domain.item.Item;
import jpabook.jpashop.repository.ItemRepository;
import jpabook.jpashop.repository.MemberRepository;
import jpabook.jpashop.repository.OrderRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class OrderService {

    private final OrderRepository orderRepository;
    private final MemberRepository memberRepository;
    private final ItemRepository itemRepository;

    // 주문
    @Transactional
    public Long order(Long memberId, Long itemId, int count){

        // 엔티티 조회
        Member member = memberRepository.findOne(memberId);
        Item item = itemRepository.findOne(itemId);

        // 배송정보 생성
        Delivery delivery = new Delivery();
        delivery.setAddress(member.getAddress());

        // 주문상품 생성
        OrderItem orderItem = OrderItem.createOrderItem(item, item.getPrice(), count);

        // 주문 생성
        Order order = Order.createOrder(member, delivery, orderItem);

        // 주문 저장
        orderRepository.save(order);

        return order.getId();
    }

    // 주문 취소
    @Transactional
    public void cancelOrder(Long orderId){

        // 주문 엔티티 조회
        Order order = orderRepository.findOne(orderId);

        // 주문 취소
        order.cancel();
    }

    // 주문 검색
    // public List<Order> findOrders(OrderSearch orderSearch) {
    //     return orderRepository.findAll(orderSearch);
    // }
}

 

참고) 예제를 단순화하려고 한 번에 하나의 상품만 주문할 수 있다.

 

- 주문 order() : 주문하는 회원 식별자, 상품 식별자, 주문 수량정보를 받아서 실제 주문엔티티를 생성한 후 저장한다.

- 주문취소 cancelOrder() : 주문 식별자를 받아서 주문 엔티티를 조회한 후 주문 엔티티에 주문취소를 요청한다.

- 주문검색 findOrders() : OrderSearch라는 검색조건을 가진 객체로 주문 엔티티를 검색한다. 자세한 내용은 다음에 나오는 주문검색 기능에서 알아보자.

 

참고) 주문서비스의 주문과 주문취소 메서드를 보면 비즈니스 로직 대부분이 엔티티에 있다. 서비스 계층은 단순히 엔티티에 필요한 요청을 위임하는 역할을 한다. 엔티티가 비즈니스 로직을 가지고 객체 지향의 특성을 적극 활용하는 것을 도메인 모델 패턴(http://martinfowle.com/eaaCatalog/domainModel.html)이라 한다.

 

반대로 엔티티에는 비즈니스 로직이 거의 없고 서비스 계층에서 대부분의 비즈니스 로직을 처리하는 것을 트랜잭션 스크립트 패턴(http://martinfowler.com/eaaCatalog/transactionScript.html)이라 한다.