도메인 검증 책임은 어디에 둘까요? – Service vs Facade, 저는 이렇게 선택했습니다

2025. 8. 1. 14:49·Spring

문제 정의

DDD 스타일로 계층을 분리하여 개발을 진행하다 보면 자연스럽게 다음과 같은 고민을 하게 됩니다.

 

“도메인 객체의 유효성 검증은 어느 계층에서 수행하는 것이 좋을까?”
도메인을 Service에서 조회하고 검증까지 할 것인지,
혹은 Facade에서 검증 책임까지 맡을 것인지에 대한 결정입니다.

 

예를 들어, ProductOption이 현재 판매 중인지 확인해야 하는 상황에서는 다음 두 가지 접근 방식이 존재합니다.


두 가지 방식: Service vs Facade

✅ 방식 A – Service에서 도메인 조회 및 검증

// ProductOptionService
public ProductOption isOnSales(Long productOptionId) {
    ProductOption productOption = productOptionRepository.findById(productOptionId)
        .orElseThrow(() -> new CoreException(...));
    productOption.isOnSales(); // 도메인 객체의 검증 메서드 호출
    return productOption;
}

 

- Service가 도메인 조회와 검증을 모두 담당합니다.

- Facade는 흐름 조립만 수행합니다.

 

 

✅ 방식 B – Facade에서 도메인 조회 및 검증

// OrderFacade
ProductOption productOption = productOptionRepository.findById(productOptionId)
        .orElseThrow(() -> new CoreException(...));
productOption.isOnSales(); // 검증 호출

 

- 도메인 조회와 검증이 모두 Facade에 명시됩니다.

- Service는 단순히 조회만을 수행합니다.


장단점 비교

항목 방식 A – Service 검증 방식 B – Facade에서 검증
비즈니스 흐름의 명확성 흐름이 Service 내부에 숨겨져 있음 흐름이 Facade에서 명확히 드러남
재사용성 검증 포함 메서드를 다양한 흐름에서 재사용 가능 검증 로직 중복 가능성 있음
단위 테스트 용이성 Service 단위로 검증 가능 검증 로직이 여러 테스트에 분산될 수 있음
역할 분리 Service가 유효성 검증을 책임짐 Facade가 흐름과 검증을 모두 담당
코드 집중도 검증 책임이 Service에 집중됨 책임이 퍼져서 관리가 어려울 수 있음

 

저는 A 방식을 선택했습니다

이 고민은 “정답이 있다기보다는 상황과 관점에 따라 달라질 수 있다”는 점을 전제로 시작해야 한다고 생각합니다.

저 역시 처음에는 Facade에서 직접 검증하는 방식(B) 이 더 직관적이고 명확해 보였고, 그렇게 구현해보기도 했습니다.

 

하지만 실제로 여러 유스케이스를 구현하고 테스트하면서 다음과 같은 이유로 A 방식이 더 적합하다고 판단하게 되었습니다.


선택한 이유

1. 재사용성과 테스트 효율성

도메인 검증을 Service에서 수행하면, 검증 로직을 여러 흐름에서 재사용하기 쉬우며

단위 테스트를 작성할 때도 Facade가 아닌 Service 단위에서 검증이 가능합니다.

 

2. 책임의 명확한 분리

Service는 검증된 도메인을 반환하는 역할을 하고,

Facade는 비즈니스 흐름을 조합하는 데에만 집중할 수 있어 역할이 명확해집니다.

 

3. 코드의 의도 파악이 쉬움

도메인은 항상 “검증된 상태”로 Facade에 전달된다는 보장이 생기기 때문에,

흐름을 읽는 입장에서도 Service를 신뢰하고 개발할 수 있습니다.


회고

이번 고민을 통해 저 자신도 다시 한번 느낄 수 있었습니다.

 

“내가 당연하다고 여기는 구조도, 실제로는 다른 시선에서 보면 더 나은 대안이 있을 수 있다.”

 

어쩌면 Facade에서 검증하는 방식(B)이 더 명확하고 실용적인 선택일 수도 있습니다.

하지만 저는 비즈니스 흐름과 검증 책임을 명확히 나누고,

Service가 책임을 지고 검증된 도메인을 반환하는 구조가

더 나은 개발 경험을 제공한다고 판단하였습니다.


결론

  • Service에서 검증 포함 → 재사용성과 테스트 용이성 향상
  • Facade는 흐름 조립 전용 → 유스케이스가 더 명확하게 드러남

👉 그래서 저는 Service에서 검증 책임을 포함하는 방식(A) 을 선택했습니다.

 

'Spring' 카테고리의 다른 글

ApplicationEvent로 비즈니스 경계 나누기: 고민과 선택  (3) 2025.08.28
결제 시스템에 Circuit Breaker를 도입하며 – 계층별 책임 분리와 안정성 확보 전략  (1) 2025.08.22
DB 인덱스 설계와 Redis 캐싱(Port-Adapter) 적용기  (2) 2025.08.15
Spring 트랜잭션 핵심 정리  (2) 2025.08.08
@Transactional 내부 호출 문제와 해결 방법  (0) 2025.03.12
'Spring' 카테고리의 다른 글
  • 결제 시스템에 Circuit Breaker를 도입하며 – 계층별 책임 분리와 안정성 확보 전략
  • DB 인덱스 설계와 Redis 캐싱(Port-Adapter) 적용기
  • Spring 트랜잭션 핵심 정리
  • @Transactional 내부 호출 문제와 해결 방법
JoshDev
JoshDev
    • 분류 전체보기 (24)
      • Java (3)
      • Spring (9)
      • Test Code (2)
      • WIL (6)
      • Vue.js (2)
      • WEB (0)
      • DB (1)
        • MySQL (1)
  • 인기 글

  • hELLO· Designed By정상우.v4.10.4
JoshDev
도메인 검증 책임은 어디에 둘까요? – Service vs Facade, 저는 이렇게 선택했습니다
상단으로

티스토리툴바