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

퍼사드(Facade) 패턴 - 구조 패턴 (Structural Patterns)

by 김 민 준 2024. 5. 23.

 

퍼사드 패턴은 복잡한 서브 시스템에 대한 단순화된 인터페이스를 제공하여, 사용자가 복잡한 시스템을 쉽게 사용할 수 있도록 돕는 디자인 패턴이다. 여러 클래스의 복잡한 상호작용을 감추고, 단순한 인터페이스를 통해서만 시스템에 접근할 수 있게 한다.

 

1. 단순한 인터페이스 제공 : 서브 시스템의 복잡한 인터페이스를 단순화하여 제공한다.

2. 복잡성 은닉 : 서브시스템의 내부 동작을 숨기고 사용자는 퍼사드 인터페이스를 통해서만 시스템을 사용할 수 있다. 

3. 서브시스템과의 독립성 : 퍼사드는 서브 시스템과 클라이언트 코드 간의 의존성을 줄여준다.

 

개발자라면 평소에도 퍼사드 패턴의 사용자이다.

어떤 뜻인지 이해가 안될 수 있는데 우리는 평소에도 많은 라이브러리와 프레임워크를 이용한다.

이게 사실은 퍼사드 패턴으로 제공된것을 우리가 사용자 입장에서 사용하고 있다고 이해하면 쉽다. 

 

그러면 우리는 퍼사드 패턴을 이용하여 어떤 기능을 구현할 수 있을까? 

 

이번 이커머스 프로젝트에서 나는 공통 모듈을 개발하는 개발자라고 생각해보자. 나는 복잡성을 사용자에게 최대한 감추고 유지보수에 무리 없으며, 재사용성도 좋은 모듈을 개발해야한다. 각 서비스의 기능을 독립적으로 처리하기 위해서 MSA 아키텍처로 개발을 진행해야 한다.

 

구현해야할 서비스는 유저서비스, 주문서비스, 결제서비스이다. 

 

아래 소스코드와 같이 우선 서비스 클래스를 3개 선언한다.

// UserService 클래스: 사용자 관련 기능 제공
class UserService {
    public void getUserDetails(String userId) {
        System.out.println("Fetching user details for user: " + userId);
    }
}

// OrderService 클래스: 주문 관련 기능 제공
class OrderService {
    public void createOrder(String userId, String product) {
        System.out.println("Creating order for user: " + userId + " for product: " + product);
    }
}

// PaymentService 클래스: 결제 관련 기능 제공
class PaymentService {
    public void processPayment(String userId, double amount) {
        System.out.println("Processing payment of $" + amount + " for user: " + userId);
    }
}

 

 

이커머스 퍼사드 클래스를 선언한다.

 

// ECommerceFacade 클래스: 퍼사드 역할
class ECommerceFacade {
    private UserService userService;
    private OrderService orderService;
    private PaymentService paymentService;

    public ECommerceFacade() {
        this.userService = new UserService();
        this.orderService = new OrderService();
        this.paymentService = new PaymentService();
    }

    public void completeOrder(String userId, String product, double amount) {
        userService.getUserDetails(userId);
        orderService.createOrder(userId, product);
        paymentService.processPayment(userId, amount);
    }
}

 

 

사용 예시 

// 사용 예시
public class FacadePatternDemo {
    public static void main(String[] args) {
        ECommerceFacade ecommerce = new ECommerceFacade();
        ecommerce.completeOrder("user123", "laptop", 999.99);
    }
}

 

//Fetching user details for user: user123
//Creating order for user: user123 for product: laptop
//Processing payment of $999.99 for user: user123

 

이렇게 구현된 서비스들을 통해 사용자에 대한 정보 그리고 제품 정보 그리고 가격까지 한번에 이커머스의 핵심 기능을 구현할 수 있다. 

 

 

과거에는 모듈개발자가 초기에 공통 모듈을 쭉 만들어 두고 동료들에게 사용하는 방법을 가이드해주거나 했지만 현재는 많은 회사가 MSA기반으로 시스템을 운영하고 있기에 당장에도 다른 동료에게 내가 만든 기능을 사용할 수 있게 해야하는 경우가 빈번하다. 물론 복잡성이 증가하기도 하고, 많은 서비 시스템을 호출하는 상황에서 불필요하게 오버헤드가 발생할 수 있긴 하다. 이에 따라서 단점을 고려하고, 요구사항을 신중히 분석해서 적절한 수준의 추상화를 유지할 수 있도록 하는것이 중요하다.