1. 퍼사드 패턴 (Facade Pattern)
Facade는 "건물의 정면"을 의미하는 단어로, 어떤 소프트웨어의 다른 커다란 코드 부분에 대해 간략화 된 인터페이스를 제공해주는 디자인 패턴을 의미합니다. 즉, 건물의 정면만을 보고 건물의 복잡한 내부는 감추는 것과 동일한 셈이죠. 퍼사드 객체는 복잡한 소프트웨어 바깥쪽의 코드가 라이브러리의 안쪽 코드에 의존하는 일을 감소시켜 주고, 복잡한 소프트웨어를 사용할 수 있게 간단한 인터페이스를 제공해줍니다.
ex) 영화를 상영하는 과정
어떤 사람이 영화를 보고자 하는데, 영화를 보기 위해서는 다음과 같은 과정을 거치게 됩니다.
음료 및 팝콘 준비 → TV 켜기 → 영화 검색 → 영화 결제 → 영화 재생
[ 코드로 보기 ]
public void view() {
Beverage beverage = new Beverage("콜라");
RemoteControl remote = new RemoteControl();
Movie movie = new Movie("스파이더맨");
beverage.Prepare();
remote.turnOn();
movie.searchMovie();
movie.chargeMovie();
movie.playMovie();
}
사용자 입장에서는 영화를 보기 위해 저런 복잡한 코드를 사용하여 영화를 봐야 한다는 것이죠. 여기서 퍼사드 객체가 등장하게 되는데 퍼사드는 이런 사용자의 영화를 보기위해 사용하는 서브 클래스들 사이의 간단한 통합 인터페이스를 제공해주는 역할을 하게 됩니다.
2. 퍼사드 패턴의 구조
Client 입장에서는 Facade 객체에서 제공하는 메서드를 호출하여 복잡한 서브 클래스의 사용을 도와줍니다.
🔍 그렇다면, 이제 예제에 Facade 객체를 추가한 형태를 살펴볼까요 ?
[ RemoteControl ]
public class RemoteControl {
public void turnOn(){
System.out.println("TV를 켜다.");
}
public void turnOff(){
System.out.println("TV를 끄다.");
}
}
리모컨을 조작하는 클래스로, 복잡한 서브 클래스 중 하나입니다.
[ Movie ]
public class Movie {
private String name;
public Movie(String name)
{
this.name = name;
}
public void searchMovie()
{
System.out.println(name+" 영화를 찾다");
}
public void chargeMovie()
{
System.out.println("영화를 결제하다");
}
public void playMovie()
{
System.out.println("영화 재생");
}
}
영화 재생 관련 클래스로, 복잡한 서브 클래스 중 하나입니다.
[ Beverage ]
public class Beverage {
private String name;
public Beverage(String name)
{
this.name = name;
}
public void prepare()
{
System.out.println(name+" 음료 준비 완료 ");
}
}
음료를 제공하는 클래스로, 복잡한 서브 클래스 중 하나입니다.
[ Facade ]
public class Facade {
private String beverageName;
private String movieName;
public Facade(String beverageName, String movieName){
this.beverageName = beverageName;
this.movieName = movieName;
}
public void viewMovie(){
Beverage beverage = new Beverage(beverageName);
RemoteControl remote = new RemoteControl();
Movie movie = new Movie(movieName);
beverage.prepare();
remote.turnOn();
movie.searchMovie();
movie.chargeMovie();
movie.playMovie();
}
}
다음으로 가장 핵심이 되는 Facade 클래스입니다. 복잡한 서브 클래스들에 대한 인스턴스를 가지며 복잡한 호출 방식에 대해 viewMovie() 메서드내에서 구현을 하도록 했습니다.
[ Viewer ]
public class Viewer {
public void view(){
Facade facade = new Facade("콜라", "어벤져스");
facade.viewMovie();
}
}
사용자 입장에서는 이제 서브 클래스에 대해 알 필요가 없겠죠 ? 단지 Facade 객체의 viewMovie() 메서드를 호출하면서 서브 클래스들의 복잡한 기능을 수행할 수 있기 때문입니다.
그럼 퍼사드 패턴을 적용한 코드의 구조를 살펴볼까요 ?
퍼사드를 적용한 전체 흐름의 구조는 이렇게 바뀝니다 ! 딱 봐도 결합도가 낮아졌을 뿐 아니라, Client 입장에서 훨씬 부담이 덜하겠죠 ?
3. 퍼사드 패턴의 장단점
(1) 장점
- Subsystem 간의 결합도를 낮출 수 있다.
- Client 입장에서 Subsystem을 사용해야 할 때 다루어야 할 객체의 수를 줄여준다.
- 클라이언트 입장에서 좀 더 간결하게 코드를 알아볼 수 있게 해준다.
(2) 단점
- Client에게 내부 Subsystem 까지 숨길 수 없다.
- Client가 Subsystem 내부의 클래스를 직접 사용하는 것을 막을 수 없다.
< 참고 자료 >