Design Pattern/구조 패턴(Structural patterns)

Facade Pattern, 퍼사드 패턴

codeyaki 2024. 2. 7. 22:35
반응형

퍼사드 패턴이란?

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

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

 

왜 사용해야 하는가?

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

언제 사용해야 하는가?

  • 복잡한 서브시스템을 단순화할 때
  • 서브시스템과 인터페이스를 통일하고 싶을 때
  • 서브시스템 간 의존성을 낮추고 싶을 때
  • 클라이언트 코드를 간소화하고 싶을 때
퍼사드 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();
    }
}

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

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