Facade
Facade는 복잡한 서브시스템 묶음에 단순화된 인터페이스를 씌우는 구조 패턴입니다. 클라이언트가 여러 클래스의 초기화 순서, 의존 관계, 호출 규약을 알 필요 없이 하나의 메서드로 원하는 결과를 얻게 해 줍니다. 호텔 프런트 데스크와 비슷합니다. 투숙객이 방 배정, 키 발급, 조식 예약을 각 부서에 따로 연락하지 않아도 프런트에서 한 번에 처리해 줍니다. 뒤에서 여러 부서가 움직이지만, 투숙객이 신경 쓸 필요는 없습니다.
▶아키텍처 다이어그램
🔍 구조 다이어그램점선 애니메이션은 데이터 또는 요청의 흐름 방향을 나타냅니다
시스템이 커지면 하나의 기능을 완수하기 위해 여러 서브시스템을 특정 순서로 호출해야 하는 상황이 생깁니다. 주문 하나를 처리하려면 인증 확인, 재고 조회, 결제 요청, 알림 발송을 순서대로 호출해야 하고, 각 서브시스템의 초기화 방법과 에러 처리 규약이 다릅니다. 이 로직이 클라이언트 코드에 직접 들어가면, 같은 조합 로직이 여러 곳에 중복됩니다. 서브시스템 하나의 인터페이스가 바뀌면 그걸 호출하는 모든 클라이언트가 영향을 받습니다. 클라이언트 입장에서는 '주문을 넣고 싶을 뿐'인데, 내부 구조를 전부 알아야 하는 상황이 문제입니다.
GoF 디자인 패턴에서 구조 패턴으로 분류됩니다. 1990년대 객체지향 시스템이 커지면서 클래스 수가 수십, 수백 개로 늘어났고, 클라이언트 코드가 서브시스템 내부 클래스를 직접 의존하는 것이 유지보수의 병목이 됐습니다. 오늘날에도 마이크로서비스 조합, SDK 설계, API Gateway처럼 '복잡한 내부를 단순한 인터페이스로 감싸야 하는' 상황은 동일합니다. 프레임워크와 라이브러리가 Facade를 내부적으로 쓰는 경우도 많습니다. jQuery가 브라우저 DOM API의 Facade였고, ORM의 `save()` 메서드가 SQL 생성, 커넥션 관리, 트랜잭션 처리의 Facade입니다.
Facade의 구조는 단순합니다. Facade 클래스가 서브시스템 객체들의 참조를 갖고 있고, 클라이언트에게 단순한 메서드를 노출합니다. 동작 순서는 이렇습니다. 1. Client가 Facade의 `doSomething()`을 호출합니다. 2. Facade 내부에서 SubsystemA, SubsystemB, SubsystemC를 적절한 순서로 호출합니다. 3. 각 서브시스템의 결과를 조합하거나 에러를 처리한 뒤 Client에 반환합니다. 중요한 점은 Facade가 서브시스템을 숨기되 가두지는 않는다는 것입니다. 클라이언트가 필요하면 서브시스템에 직접 접근할 수 있습니다. Facade는 강제가 아니라 편의입니다. 이것이 Facade를 단순한 래퍼와 구별하는 핵심입니다.
Facade와 Adapter는 둘 다 기존 코드를 감싸는 패턴이지만 의도가 다릅니다. Adapter는 인터페이스 불일치를 해결하는 것이 목적이고, Facade는 복잡성을 줄이는 것이 목적입니다. Adapter가 감싸는 대상은 보통 하나이고 인터페이스를 변환하지만, Facade는 여러 서브시스템을 묶어 단순한 진입점을 만듭니다. Facade와 Mediator도 비교됩니다. 둘 다 여러 객체 사이의 통신을 조율하지만, Facade는 단방향으로 단순화하는 데 초점이 있고 Mediator는 객체들 간의 양방향 상호작용을 중재합니다. Facade를 쓸 시점은 '클라이언트가 내부 구조를 몰라도 되는가'로 판단합니다. 내부를 알아야만 제대로 쓸 수 있는 상황이면 Facade가 오히려 추상화 누수를 만들 수 있습니다.
Facade는 계층 경계에서 가장 자주 쓰입니다. 컨트롤러가 여러 서비스를 직접 조합하는 대신, Application Service 레이어가 Facade 역할을 맡아 하나의 유스케이스를 하나의 메서드로 표현하면, 컨트롤러는 HTTP 요청 파싱에만 집중할 수 있습니다. SDK 설계에서도 핵심입니다. AWS SDK의 `s3.upload()`가 멀티파트 분할, 재시도, 권한 확인을 내부에서 처리하는 것이 Facade입니다. 사용자는 파일과 버킷 이름만 주면 됩니다. 다만 Facade가 너무 많은 책임을 갖게 되면 God Object로 변질됩니다. Facade 하나가 수십 개의 메서드를 갖거나, 서브시스템 간의 복잡한 조건 분기를 직접 처리하기 시작하면, 그 Facade 자체가 새로운 복잡성의 원천이 됩니다. Facade는 조율만 하고, 비즈니스 로직은 서브시스템에 남겨 두는 것이 건강한 구조입니다.