
트랜잭션 스크립트와 도메인 모델 차이는 종종 “옛날 방식 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가 잘 버틸까
- 규칙이 적다
- 상태 전환이 단순하다
- 정책 변경이 드물다
- 객체보다 요청 처리 흐름이 더 중요하다
이 조건에서는 굳이 도메인 모델을 세워도 얻는 이익이 크지 않을 수 있습니다. 오히려 구조만 무거워지고, 팀원이 이해하기 더 어려워질 수도 있습니다.
언제부터 도메인 모델이 더 유리해질까
문제는 규칙과 상태 전환이 커질 때 시작됩니다. 승인 조건이 여러 서비스에 퍼지고, 같은 검증이 반복되고, 정책 하나가 바뀌면 수정 지점이 넓어지는 순간부터 절차 코드의 비용이 커집니다.
- 상태 전환 규칙이 늘어난다
- 같은 정책이 여러 유즈케이스에 반복된다
- 객체 무결성을 외부에서 계속 지켜야 한다
- 변경 하나가 여러 서비스에 퍼진다
이때는 domain model이 “멋져 보여서”가 아니라, 규칙의 주인을 모으기 위해 더 유리해집니다.
자주 하는 오해
도메인 모델이 항상 더 고급이다
아닙니다. 규칙이 거의 없는 CRUD 관리자 화면까지 억지로 도메인 모델로 만들면 과설계일 수 있습니다.
트랜잭션 스크립트는 무조건 나쁘다
그렇지도 않습니다. 작은 서비스, 단순한 정책, 짧은 수명 제품에서는 아주 현실적인 선택일 수 있습니다.
빈혈 도메인 모델만 피하면 된다
문제는 패턴 이름보다 규칙의 분산입니다. 이 점은 빈혈 도메인 모델 글과도 이어집니다.
실전 판단 기준
- 규칙보다 요청 처리 흐름이 더 중요하면 transaction script가 유리하다
- 상태 무결성과 정책 변화가 크면 domain model이 유리하다
- 같은 규칙이 반복되면 객체 안으로 모을 시점일 수 있다
- 팀이 감당할 수 있는 복잡도도 함께 봐야 한다
마무리
용어 정의 자체는 Fowler의 Transaction Script 설명과 Domain Model 설명을 보면 더 간결하게 잡을 수 있습니다.
트랜잭션 스크립트와 도메인 모델 차이는 선악의 문제가 아니라, 도메인 복잡도와 변경 압력의 문제에 더 가깝습니다. 작은 CRUD 서비스는 transaction script로도 충분히 잘 갈 수 있고, 규칙이 커지면 domain model이 더 자연스러워집니다.
중요한 것은 패턴 이름이 아니라 지금 시스템의 규칙이 어디에 흩어지고 있는지를 보는 일입니다. 그 관점을 잡으면 과설계도, 무리한 단순화도 조금 덜 하게 됩니다.