1. 파사드 패턴이란?
- 파사드(Facade) 패턴은 복잡한 서브시스템에 대한 간단한 인터페이스를 제공하는 구조적 디자인 패턴입니다.
- 이 패턴은 라이브러리, 프레임워크 또는 복잡한 클래스 집합에 대한 단순화된 인터페이스를 제공합니다.
- 파사드는 클라이언트가 복잡한 서브시스템의 내부 동작을 이해하지 않고도 필요한 기능을 쉽게 사용할 수 있게 합니다.
1.1 파사드 패턴의 목적
- 복잡한 시스템의 사용 난이도를 낮춤
- 서브시스템에 대한 의존성 감소
- 클라이언트 코드와 서브시스템 간의 결합도 감소
- 코드의 가독성과 유지보수성 향상
2. 문제 상황
- 복잡한 라이브러리나 프레임워크를 사용할 때 많은 객체를 초기화하고, 의존성을 추적하며, 올바른 순서로 메서드를 실행해야 합니다.
- 이로 인해 비즈니스 로직이 서드파티 클래스의 구현 세부사항과 강하게 결합되어 코드 이해와 유지보수가 어려워집니다.
2.1 실생활 예시
- 전화로 상품을 주문할 때 상담원은 주문 시스템, 결제 게이트웨이, 배송 서비스 등 가게의 모든 서비스와 부서에 대한 파사드 역할을 합니다.
- 상담원은 복잡한 주문 시스템의, 단순한 음성 인터페이스를 제공합니다.
팁
파사드 패턴은 마치 복잡한 기계의 간단한 제어판과 같습니다. 내부 작동 방식은 복잡하지만, 사용자(클라이언트)는 몇 개의 버튼만 눌러 원하는 기능을 사용할 수 있습니다.
3. 파사드 패턴의 구조
3.1 주요 구성 요소

- 파사드(Facade): 서브시스템의 기능에 대한 편리한 접근을 제공하는 클래스입니다. 클라이언트 요청을 어디로 전달할지 알고 있으며 모든 구성 요소를 작동시키는 방법을 알고 있습니다.
- 추가 파사드(Additional Facade): 단일 파사드에 관련 없는 기능들로 오염되는 것을 방지하기 위해 생성할 수 있는 클래스입니다.
- 복잡한 서브시스템(Complex Subsystem): 수십 개의 다양한 객체로 구성됩니다. 서브시스템 클래스들은 파사드의 존재를 알지 못하며, 시스템 내에서 서로 직접 작동합니다.
- 클라이언트(Client): 서브시스템 객체를 직접 호출하는 대신 파사드를 사용합니다.
3.2 구조 다이어그램
+----------------+ +----------------+
| Client |----->| Facade |
+----------------+ +----------------+
|
|
v
+--------------+
| |
+----->| Subsystem A |
| | |
| +--------------+
|
| +--------------+
| | |
+----->| Subsystem B |
| | |
| +--------------+
|
| +--------------+
| | |
+----->| Subsystem C |
| |
+--------------+
4. 파사드 패턴 구현 방법
4.1 구현 단계
- 기존 서브시스템보다 간단한 인터페이스를 제공할 수 있는지 확인합니다.
- 새로운 파사드 클래스에서 이 인터페이스를 선언하고 구현합니다.
- 파사드는 클라이언트 코드의 호출을 서브시스템의 적절한 객체로 리디렉션해야 합니다.
- 모든 클라이언트 코드가 오직 파사드를 통해서만 서브시스템과 통신하도록 합니다.
- 파사드가 너무 커진다면, 그 동작의 일부를 새로운 파사드 클래스로 추출하는 것을 고려합니다.
4.2 코드 예제
다음은 복잡한 비디오 변환 프레임워크에 대한 파사드 패턴 구현 예시입니다.
복잡한 서브시스템 클래스
// 복잡한 서드파티 비디오 변환 프레임워크의 일부 클래스입니다.
// 우리는 이 코드를 제어할 수 없으므로 단순화할 수 없습니다.
class VideoFile {
private String name;
public VideoFile(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class OggCompressionCodec {
// 구현 생략
}
class MPEG4CompressionCodec {
// 구현 생략
}
class CodecFactory {
public static Codec extract(VideoFile file) {
// 코덱 추출 로직
return new OggCompressionCodec();
}
}
class BitrateReader {
public static byte[] read(VideoFile file, Codec codec) {
// 파일 읽기 로직
return new byte[0];
}
public static byte[] convert(byte[] buffer, Codec codec) {
// 변환 로직
return new byte[0];
}
}
class AudioMixer {
public byte[] fix(byte[] audioData) {
// 오디오 수정 로직
return new byte[0];
}
}
interface Codec {
// 코덱 인터페이스
}
파사드 클래스 구현
class VideoConverter {
public File convert(String filename, String format) {
VideoFile file = new VideoFile(filename);
Codec sourceCodec = CodecFactory.extract(file);
Codec destinationCodec;
if (format.equals("mp4")) {
destinationCodec = new MPEG4CompressionCodec();
} else {
destinationCodec = new OggCompressionCodec();
}
byte[] buffer = BitrateReader.read(file, sourceCodec);
byte[] result = BitrateReader.convert(buffer, destinationCodec);
result = (new AudioMixer()).fix(result);
return new File(result);
}
}
- 프레임워크의 복잡성을 간단한 인터페이스 뒤에 숨기는 파사드 클래스를 생성합니다.
VideoConverter클래스는 비디오 파일을 변환하는 단순한 메서드convert를 제공합니다.- 이 메서드는 내부적으로 복잡한 서브시스템의 여러 클래스를 사용하여 비디오 파일을 변환합니다.
- 클라이언트는
VideoConverter클래스의convert메서드만 호출하면 됩니다.