본문 바로가기
Design Pattern/구조 패턴(Structural patterns)

Facade Pattern, 퍼사드 패턴

by codeyaki 2024. 2. 7.
반응형

퍼사드 패턴이란?

일단 퍼사드의 의미는 건물의 출입구로 이용되는 정면을 의미한다 

이와 마찬가지로 디자인패턴에서의 퍼사드 또한 여러 복잡한 서브시스템들을 묶어 단순한 인터페이스로 제공하는 것이다.

 

왜 사용해야 하는가?

  • 클라이언트가 복잡한 서브시스템들과 직접 상호작용할 필요 없이, 퍼사드를 통해 손쉽게 사용할 수 있다.
  • 서브시스템의 변경이 클라이언트 코드에 영향을 최소화할 수 있다.

언제 사용해야 하는가?

  • 복잡한 서브시스템을 단순화할 때
  • 서브시스템과 인터페이스를 통일하고 싶을 때
  • 서브시스템 간 의존성을 낮추고 싶을 때
  • 클라이언트 코드를 간소화하고 싶을 때
퍼사드 vs 어댑터 vs 데코레이터
퍼사드 => 인터페이스 간소화
어댑터 => 서로 다른 인터페이스 호환
데코레이트 => 인터페이스 기능 추가

 

문제점

  • 새로운 기능이 추가하거나 기존 기능을 수정할 때 퍼사드 클래스 또한 변경해야 한다.
  • 퍼사드 패턴을 과도하게 사용하면 오히려 복잡성을 증가시킬 수 있다.

구현 예시

우리가 온라인 주문할 때를 예로 들어서 구현해 보자

먼저 아래와 같이 결제 시스템, 재고 시스템, 배송 시스템이 있다고 했을 때 

package com.example.designpattern.stuctural.facade.subsystem;

public class PaymentSystem {
    public void processPayment() {
        System.out.println("결제가 완료되었습니다.");
    }
}
package com.example.designpattern.stuctural.facade.subsystem;

public class InventorySystem {

    public void updateInventory() {
        System.out.println("재고 업데이트가 완료되었습니다.");
    }
}

 

package com.example.designpattern.stuctural.facade.subsystem;

public class ShippingSystem {
    public void shipOrder() {
        System.out.println("배송 처리가 완료되었습니다.");
    }
}

제품을 온라인 주문을 하기 위해서는 결제 -> 재고업데이트 -> 배송의 절차를 가져야 한다. (실제로는 좀 더 복잡하겠지만 간단하게..)

그렇다면 주문을 구현하기 위해서 클라이언트 시스템에서 이 과정을 모두 작성하는 것이 좋을까?

 

예시에서는 간단하여서 실수할 가능성은 적겠지만 이보다 더욱 복잡한 서브시스템으로 구성되어 있는 로직이라면 어떻게 될까... 실수할 가능성은 매우 높아지게 된다.

따라서 클라이언트 쪽에서 간단하게 사용할 수 있도록 중간에 퍼사드 객체를 만들어서 해결해 줄 수 있다.

package com.example.designpattern.stuctural.facade.facade;

import com.example.designpattern.stuctural.facade.subsystem.InventorySystem;
import com.example.designpattern.stuctural.facade.subsystem.PaymentSystem;
import com.example.designpattern.stuctural.facade.subsystem.ShippingSystem;

public class OnlineOrderFacade {
    private InventorySystem inventorySystem;
    private PaymentSystem paymentSystem;
    private ShippingSystem shippingSystem;

    public OnlineOrderFacade() {
        this.inventorySystem = new InventorySystem();
        this.paymentSystem = new PaymentSystem();
        this.shippingSystem = new ShippingSystem();
    }

    public void placeOrder() {
        System.out.println("온라인 주문하기");
        paymentSystem.processPayment();
        inventorySystem.updateInventory();
        shippingSystem.shipOrder();
        System.out.println("온라인 주문이 완료되었습니다.");
    }
}

placeOrder 메서드를 통해서 해당 과정들을 한 번에 진행할 수 있도록 만들어서 클라이언트가 간단하게 사용할 수 있도록 만들어 주었다.

 

package com.example.designpattern.stuctural.facade;

import com.example.designpattern.stuctural.facade.facade.OnlineOrderFacade;

public class FacadeClient {
    public static void main(String[] args) {
        OnlineOrderFacade onlineOrderFacade = new OnlineOrderFacade();
        onlineOrderFacade.placeOrder();
    }
}

이렇게 간단하게 사용하면 복잡한 서비스가 한큐에 실행된다!

온라인 주문하기
결제가 완료되었습니다.
재고 업데이트가 완료되었습니다.
배송 처리가 완료되었습니다.
온라인 주문이 완료되었습니다.
반응형