본문 바로가기
프로그래밍/CS

[Design Pattern] Domain Model Pattern vs Transaction Script Pattern

by so5663 2023. 6. 26.

트랜잭션 스크립트(Transaction Script) 패턴?

 

엔티티에 비지니스로직이 거의 없고, 서비스 계층에서 비즈니스 로직을 처리하는 방법을 가리킵니다.

엔티티는 단순하게 데이터를 전달하는 역할이 되면서 서비스 로직이 커지게 됩니다.

현재 재직중인 회사에서 주로 사용하는 방법입니다.

   public class SomeTransactionScript {
        public Result do(...) {
            try {
            
                SomeTransaction tx = ...;
                tx.begin();
                
                // 1. 잔고확인
                ...
                // 2. 받는 사람 확인
                ...
                // 3. 이체 실행
                ...
                // 4. 잔고 감소
                ...
                tx.commit();
                
            } catch(..) {
                tx.rollback();
                ...
            } finally {
                ...
                ...
            }
        }
    }

이런 식으로 서비스에서 비즈니스 로직을 구현합니다. 

 

 

도메인 모델 (Domain Model) 패턴?

 

대부분의 비즈니스 로직이 엔티티 안에 구성되어있습니다.

서비스 계층은 엔티티에 필요한 역할을 위임하는 역할을 합니다.

엔티티 안에 비즈니스 로직을 가지고 객체지향을 활용하는 기법입니다.

@Entity
@Table(name = "orders")
@Getter @Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED) //의도하지 않은 생성자 생김 방지
public class Order {

    @Id @GeneratedValue
    @Column(name = "order_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "member_id")
    private Member member;

    @OneToMany(mappedBy = "order")
    private List<OrderItem> orderItems = new ArrayList<>();

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "delivery_id")
    private Delivery delivery;

    private LocalDateTime orderDate; //주문시간

    @Enumerated(EnumType.STRING)
    private OrderStatus status; //주문상태 [ORDER, CANCEL]

    //==연관관계 메서드==//
    public void setMemeber(Member member) {
        this.member = member;
        member.getOrders().add(this);
    }

    public void addOrderItem(OrderItem orderItem) {
        this.orderItems.add(orderItem);
        orderItem.setOrder(this);
    }

    public void setDelivery(Delivery delivery) {
        this.delivery = delivery;
        delivery.setOrder(this);
    }

    //==생성 메소드==//
    public static Order createOrder(Member member, Delivery delivery, OrderItem... orderItems) {
        Order order = new Order();
        order.setMember(member);
        order.setDelivery(delivery);
        for (OrderItem orderItem : orderItems) {
            order.addOrderItem(orderItem);
        }
        order.setStatus(OrderStatus.ORDER);
        order.setOrderDate(LocalDateTime.now());
        return order;
    }

    //==비즈니스 로직==//
    /**
     * 주문 최소
     */
    public void cancel() {
        if(delivery.getStatus() == DeliveryStatus.COMP) {
            throw new IllegalStateException("이미 배송완료된 상품은 취소가 불가능합니다.");
        }

        this.setStatus(OrderStatus.CANCEL);
        for (OrderItem orderItem : orderItems) {
            orderItem.cancel();
        }
    }

    //==조회 로직==//
    /**
     * 전체 주문 가격 조회
     */
    public int getTotalPrice() {
//        int toalPrice = 0;
//        for (OrderItem orderItem : orderItems) {
//            toalPrice += orderItem.getTotalPrice();
//        }
//        return toalPrice;

        return orderItems.stream()
                .mapToInt(OrderItem::getTotalPrice)
                .sum();
    }

}

이런식으로 엔티티 안에다가 비즈니스 로직을 구현합니다.

 

https://github.com/sohyounsoo/jpashop 전체소스

'프로그래밍 > CS' 카테고리의 다른 글

Iass vs Pass vs Sass 정리  (0) 2024.02.20
TCP란? && TCP의 헤더 정보 && 패킷 교환 방식  (1) 2023.07.26