단순화된 인터페이스로 서브시스템을 더 편리하게 사용하기 위해 사용
1. 의도
•
GoF
◦
한 서브시스템 내의 인터페이스 집합에 대한 획일화된 하나의 인터페이스를 제공하는 패턴
◦
서브시스템을 사용하기 쉽도록 상위 수준의 인터페이스 정의
•
Head First
◦
서브시스템에 있는 일련의 인터페이스를 통합 인터페이스로 묶어줍니다.
◦
또한 고수준의 인터페이스도 정의하므로 서브시스템을 더 편리하게 사용할 수 있습니다.
◦
단순화된 인터페이스로 서브시스템을 더 편리하게 사옹하기 위해 사용
2. 활용성
•
복잡한 서브시스템에 대해 단순한 인터페이스 제공이 필요할 때
•
추상 개념에 대한 구현 클래스와 사용자 사이에 너무 많은 종속성이 존재할 때
◦
퍼사드 패턴을 통해 사용자와 다른 서브 시스템 간의 결합도를 줄일 수 있음
◦
서브 시스템에 정의된 모든 인터페이스가 공개되면 빈번하게 메서드 호출이 될 수도 있음. 그러나 이러한 호출은 단순한 형태로 통합하여 제공하고 나머지 부분은 내부적으로 처리함으로써 사용자와 서브시스템 사이의 호출을 실질적으로 감소하게 해줌
•
서브 시스템을 게층화 할 때
◦
퍼사드 패턴을 통해 각 서브시스템의 계층에 대한 접근점을 제공함
◦
퍼사드를 통해서만 대화를 하므로 서브시스템 간의 종속정 제거 가능
◦
서브시스템 내부 설계의 변경이 다른 서브시스템에 독립적
3. 구조
•
UML Class Diagram
4. 참여자
참여자 | 역할 | 예시 |
Facade | 단순하고 일관된 통합 인터페이스 제공.
서브시스템을 구성하는 어떤 클래스가 어떤 요청을 처리해야 하는지 알고 있음
사용자의 요청을 해당 서브시스템 객체에 전달 | 홈시어터
(아래 서브시스템 객체에 대한 단순한 인터페이스 제공)
|
Subsystem | 서브시스템의 기능을 구현
Facade 객체로 할당된 작업을 실제로 처리
Facade 객체에 대한 아무런 정보도 없음 (참조자도 없음) | 스크린, 팝콘, 프로젝터, 스트리밍 플레이어, 스피커 |
5. 협력 방법
•
사용자는 Facade에 정의된 인터페이스를 이용해서 서브시스템과 상호작용합니다.
•
Facade는 해당 요청을 서브시스템을 구성하는 적당한 객체에게 전달합니다.
•
서브시스템을 구성하는 객체가 실제의 요청 처리를 담당하지만, 퍼사드는 서브 시스템에게 메세지를 전달하기 위해 자신의 인터페이스에 동일한 작업을 정의해야합니다.
•
퍼사드를 사용하는 사용자는 서브시스템을 구성하는 객체로 직접 접근하지 않아도 됩니다.
6. 결과
•
서브시스템의 구성요소를 보호할 수 있습니다.
◦
사용자가 다루어야하는 객체 수 줄어듦
◦
서브시스템을 쉽게 사용 가능
•
서브시스템과 사용자 코드간의 결합도를 더욱 약하게 만듬
◦
서브시스템 내의 요소를 다양화하는 작업 원활히 가능
•
응용 프로그램쪽에서 서브시스템 클래스를 사용하는 것을 완전히 막지는 않음
◦
Facade를 사용할지, 서브시스템 클래스를 직접 사용할지 결정 가능
7. 예시 코드
// Subsystem classes
class Subscription {
public selectSubscription(subscriptionType: string): void {
console.log(`Selected ${subscriptionType} subscription`);
}
}
class Movie {
public selectMovie(movieTitle: string): void {
console.log(`Selected movie: ${movieTitle}`);
}
}
class Payment {
public processPayment(paymentInfo: string): void {
console.log(`Processed payment with ${paymentInfo}`);
}
}
// Facade class
class MovieRentalFacade {
private subscription: Subscription;
private movie: Movie;
private payment: Payment;
constructor() {
this.subscription = new Subscription();
this.movie = new Movie();
this.payment = new Payment();
}
public rentMovie(subscriptionType: string, movieTitle: string, paymentInfo: string): void {
this.subscription.selectSubscription(subscriptionType);
this.movie.selectMovie(movieTitle);
this.payment.processPayment(paymentInfo);
console.log(`Rented ${movieTitle} with ${subscriptionType} subscription and ${paymentInfo} payment information.`);
}
}
// Client code
const movieRentalFacade = new MovieRentalFacade();
movieRentalFacade.rentMovie("premium", "The Godfather", "credit card");
TypeScript
복사