|

트랜잭션 스크립트와 도메인 모델 차이

트랜잭션 스크립트와 도메인 모델 차이를 설명하는 대표 이미지
단순함이 장점이 되는 순간과, 규칙 분산이 비용이 되는 순간을 구분해야 한다

트랜잭션 스크립트도메인 모델 차이는 종종 “옛날 방식 vs 좋은 방식”처럼 단순하게 소비됩니다. 하지만 실제로는 그렇게 단순하지 않습니다. 어떤 서비스는 transaction script가 더 자연스럽고, 어떤 서비스는 domain model이 아니면 규칙이 금방 흩어집니다.

이번 글에서는 Martin Fowler의 정의를 바탕으로, CRUD가 많은 서비스는 어디까지 단순하게 가도 되는지, 그리고 어느 시점부터 도메인 모델이 더 나아지는지 현실적인 판단 기준으로 정리하겠습니다.


트랜잭션 스크립트는 무엇인가

Fowler는 Transaction Script를 각 요청을 처리하는 절차 중심의 비즈니스 로직 구조로 설명합니다. 즉 요청 하나를 처리하는 서비스 메서드, 핸들러, 유즈케이스 안에 검증과 계산, 저장 흐름이 모이는 형태입니다.

public void approveOrder(long orderId) {
    Order order = orderRepository.find(orderId);
    if (order == null) throw new IllegalArgumentException();
    if (order.isCanceled()) throw new IllegalStateException();
    if (order.getTotalPrice() > 1000000) {
        notifyManager(order);
    }
    order.setApproved(true);
    orderRepository.save(order);
}

이 구조의 장점은 단순하고 읽기 쉽다는 점입니다. 흐름이 한 메서드 안에 보이기 때문에 초반 개발 속도도 빠른 편입니다.


도메인 모델은 무엇이 다른가

Fowler는 Domain Model을 데이터와 행위를 함께 가진 도메인 객체 모델로 설명합니다. 중요한 규칙과 상태 전환이 객체 안에 더 많이 들어갑니다.

class Order {
    private boolean approved;
    private boolean canceled;
    private int totalPrice;

    void approve(Notifier notifier) {
        if (canceled) throw new IllegalStateException();
        if (totalPrice > 1000000) {
            notifier.notifyManager(this);
        }
        approved = true;
    }
}

즉 서비스는 흐름을 조정하고, 중요한 규칙은 객체가 스스로 지키도록 맡기는 쪽에 더 가깝습니다.


작은 CRUD 서비스는 왜 transaction script가 잘 버틸까

  • 규칙이 적다
  • 상태 전환이 단순하다
  • 정책 변경이 드물다
  • 객체보다 요청 처리 흐름이 더 중요하다

이 조건에서는 굳이 도메인 모델을 세워도 얻는 이익이 크지 않을 수 있습니다. 오히려 구조만 무거워지고, 팀원이 이해하기 더 어려워질 수도 있습니다.


언제부터 도메인 모델이 더 유리해질까

문제는 규칙과 상태 전환이 커질 때 시작됩니다. 승인 조건이 여러 서비스에 퍼지고, 같은 검증이 반복되고, 정책 하나가 바뀌면 수정 지점이 넓어지는 순간부터 절차 코드의 비용이 커집니다.

  1. 상태 전환 규칙이 늘어난다
  2. 같은 정책이 여러 유즈케이스에 반복된다
  3. 객체 무결성을 외부에서 계속 지켜야 한다
  4. 변경 하나가 여러 서비스에 퍼진다

이때는 domain model이 “멋져 보여서”가 아니라, 규칙의 주인을 모으기 위해 더 유리해집니다.


자주 하는 오해

도메인 모델이 항상 더 고급이다

아닙니다. 규칙이 거의 없는 CRUD 관리자 화면까지 억지로 도메인 모델로 만들면 과설계일 수 있습니다.

트랜잭션 스크립트는 무조건 나쁘다

그렇지도 않습니다. 작은 서비스, 단순한 정책, 짧은 수명 제품에서는 아주 현실적인 선택일 수 있습니다.

빈혈 도메인 모델만 피하면 된다

문제는 패턴 이름보다 규칙의 분산입니다. 이 점은 빈혈 도메인 모델 글과도 이어집니다.


실전 판단 기준

  1. 규칙보다 요청 처리 흐름이 더 중요하면 transaction script가 유리하다
  2. 상태 무결성과 정책 변화가 크면 domain model이 유리하다
  3. 같은 규칙이 반복되면 객체 안으로 모을 시점일 수 있다
  4. 팀이 감당할 수 있는 복잡도도 함께 봐야 한다

마무리

용어 정의 자체는 Fowler의 Transaction Script 설명Domain Model 설명을 보면 더 간결하게 잡을 수 있습니다.

트랜잭션 스크립트와 도메인 모델 차이는 선악의 문제가 아니라, 도메인 복잡도와 변경 압력의 문제에 더 가깝습니다. 작은 CRUD 서비스는 transaction script로도 충분히 잘 갈 수 있고, 규칙이 커지면 domain model이 더 자연스러워집니다.

중요한 것은 패턴 이름이 아니라 지금 시스템의 규칙이 어디에 흩어지고 있는지를 보는 일입니다. 그 관점을 잡으면 과설계도, 무리한 단순화도 조금 덜 하게 됩니다.

함께보면 좋은 글