✅ Facade 패턴이란?

졸용·2025년 12월 2일

🔹 Facade 패턴이란?

MSA·Spring 기반

복잡한 서브시스템(여러 클래스, 여러 모듈)의 동작을 감춰주고,
“단순한 하나의 인터페이스”로 제공하는 구조적 디자인 패턴
을 말한다.

즉, “얘한테만 요청하면 내부에서 복잡한 처리 다 해줄게.”
라는 역할을 하는 대표 창구(Facade) 를 만드는 것.



🔹 왜 사용하는가?

🔸 복잡한 의존 구조를 숨겨서 코드 가독성/단순성 증가

서브 서비스가 여러 개일 때, 클라이언트 코드가 많은 서비스에 직접 의존하면 지저분함
→ Facade 하나만 바라보게 하면 API를 단순화할 수 있음.

🔸 공통 흐름을 중앙 집중화

여러 서비스 호출 순서를 일정하게 유지해야 할 때 강력함
(예: A → B → C 호출해야 하는 시나리오)

🔸 변경에 강해짐 (Low Coupling)

내부 구현이 바뀌더라도 Facade 인터페이스는 유지된다면
상위 레이어에서 영향을 최소화할 수 있음.



🔹 어떻게 동작하는가?

구조

ClientFacadeSubsystem ASubsystem BSubsystem C

Facade는 다음을 수행:

  • 여러 서브 클래스에 요청을 전달
  • 호출 순서 조율
  • 예외 처리 통합
  • 공통 트랜잭션 적용(선택)
  • 복잡한 작업을 단순 메서드 1~2개로 추상화

결과적으로 클라이언트는 “복잡성 없는 간단한 API”로 이용할 수 있게 됨.



🔹 간단 예제: 주문 생성 MSA에서의 Facade

문제 상황
Order 생성 시 다음 흐름을 자동 처리해야 한다고 해보자:

  1. 상품 재고 확인(ProductService)
  2. 요청자/수신자 업체 정보 조회(FirmService)
  3. 주문 생성(OrderService)
  4. Kafka 이벤트 발행(KafkaProducer)
  5. 배송 생성(DeliveryService)

각각을 Controller에서 직접 호출하면 지저분해짐.


🔸 Facade 적용 버전

1) Facade 클래스

@Service
@RequiredArgsConstructor
public class OrderCreationFacade {

    private final ProductService productService;
    private final FirmService firmService;
    private final OrderService orderService;
    private final KafkaProducer kafkaProducer;
    private final DeliveryService deliveryService;

    @Transactional
    public Order createOrder(CreateOrderRequest request) {

        // 1. 상품 재고 확인
        productService.checkStock(request.productId(), request.qty());

        // 2. 업체 정보 조회
        firmService.validateFirms(request.requesterFirmId(), request.receiverFirmId());

        // 3. 주문 생성
        Order order = orderService.create(request);

        // 4. Kafka 이벤트 발행
        kafkaProducer.publishOrderCreated(order);

        // 5. 배송 생성
        deliveryService.createDelivery(order);

        return order;
    }
}

2) Controller는 단순해짐

@PostMapping("/orders")
public BaseResponse<OrderResponse> create(@RequestBody CreateOrderRequest request) {

    Order order = orderCreationFacade.createOrder(request);

    return BaseResponse.ok(OrderResponse.from(order));
}

장점:

  • Controller는 1줄로 처리
  • 각 서비스 호출 순서가 중앙 집중화
  • 모듈 변경의 영향 최소화


🔹 언제 사용하면 좋을까?

🔸 사용하길 권하는 경우

  • 여러 서비스 호출 흐름이 항상 일정한 경우
  • Controller나 외부 API에서 복잡한 비즈니스 흐름을 직접 처리하고 있는 경우
  • MSA 혹은 모듈 간 통신이 많은 경우
  • 트랜잭션 묶음이 필요한 경우
  • 특정 기능의 "오케스트레이션"이 필요한 경우

🔸 사용하면 안 좋거나 과한 경우

  • 한번만 호출되는 단순 흐름
  • 서비스 간 단순한 1:1 호출만 존재할 때
  • Facade가 너무 커지면 거대한 God Class 되므로 주의


🔹 핵심 요약

항목내용
목적복잡한 서브시스템을 감추고 단일 인터페이스 제공
장점단순화, 의존성 감소, 흐름 중앙화, 변경 영향 최소화
단점과하게 사용하면 God Class 위험
활용 추천MSA, 오케스트레이션, 복잡한 업무 흐름 묶기
profile
꾸준한 공부만이 답이다

0개의 댓글