Facade
Facade Pattern
퍼사드 패턴이란?
어떤 서브시스템의 일련의 인터페이스에 대한 통합된 인터페이스를 제공
퍼사드에서 고수준 인터페이스를 정의하기 때문에 서브시스템을 더 쉽게 사용할 수 있음
클래스 패키지에 인터페이스를 제공하기 위해 사용
간단한 예를 들어보자
본래 client는 각각의 System을 알고 일일이 접근해야 했다. -> 커플링
하지만 Facade패턴을 이용해서 client는 각각의 System을 몰라도 Facade를 통해 모든 System의 기능을 사용할 수 있다!! -> 디커플링
예를 들어보자
어떤 사람이 영화를 보려고 한다. 영화를 보기 위해 다음과 같은 과정을 거치게 됨.
음료를 준비 -> TV켬 -> 영화를 검색 -> 영화를 결제 -> 영화를 재생
이와 같은 순서로 한다고 가정하자
퍼사드패턴 적용전
public void view()
{
Beverage beverage = new Beverage("콜라");
Remote_Control remote= new Remote_Control();
Movie movie = new Movie("어벤져스");
beverage.Prepare(); //음료 준비
remote.Turn_On(); //tv를 켜다
movie.Search_Movie(); //영화를 찾다
movie.Charge_Movie(); // 영화를 결제하다
movie.play_Movie(); //영화를 재생하다
}
사용자 입장에서는 영화를 보기위해 이런 복잡한 코드를 사용하여 영화를 봐야만 함. -> 퍼사드 패턴으로 서브 클래스들 사이의 간당한 통합 인터페이스를 제공하는 역할을 제공할 수 있다!!
퍼사드패턴 적용 후
public class Beverage {
private String name="";
public Beverage(String name) {this.name=name;}
public void Prepare() {System.out.println(name+" Beverage Prepare");}
}
}
public class Remote_Control {
public void Turn_On() {
System.out.println("TV ON");
}
public void Turn_Off() {
System.out.println("TV OFF");
}
}
}
public class Movie {
private String name="";
public Movie(String name) {
this.name=name;
}
public void Search_Movie() {
System.out.println(name+" Movie Search");
}
public void Charge_Movie() {
System.out.println("Charge Movie");
}
public void Play_Movie() {
System.out.println("Play Movie");
}
}
}
public class Facade {
private String beverage_name="";
private String movie_name="";
public Facade(String beverage,String movie) {
this.beverage_name=beverage;
this.movie_name=movie;
}
public void View_Movie() {
Beverage beverage=new Beverage(beverage_name);
Remote_Control remote=new Remote_Control();
Movie movie=new Movie(movie_name);
beverage.Prepare();
remote.Turn_On();
movie.Search_Movie();
movie.Charge_Movie();
movie.Play_Movie();
}
> 퍼사드객체의 View_Movie() 메서드를 통해 서브클래스들의 복잡한 기능을 수행할 수 있다.
> (사용자입장)퍼사드 클래스에서 Remote_control 이나 Beverage, Movie객체를 알 필요가 없다!
퍼사드의 메서드만 알면 된다
+ 기능이 추가되더라도 클라이언트는 아무런 변경이 없다
비슷한 예시로 참고할 수 있는 것(홈시어터 컴포넌트 조작)
public class HomeTheaterFacade {
// 구성부분 : 우리가 사용하고자하는 서브시스템의 모든 구성요소들이
인스턴스 변수형태로 저장된다.
Amplifier amp;
Tuner tuner;
DvdPlayer dvd;
CdPlayer cd;
Projector projector;
TheaterLights lights;
Screen screen;
PopcornPopper popper;
// Facade의 생성자에는 서브시스템의 각 구성요소의 레퍼런스가 전달된다.
// Facade에서는 각 레퍼런스를 인스턴스 변수에 저장한다.
public HomeTheaterFacade(Amplifier amp,
Tuner tuner,
DvdPlayer dvd,
CdPlayer cd,
Projector projector,
Screen screen,
TheaterLights lights,
PopcornPopper popper) {
this.amp = amp;
this.tuner = tuner;
this.dvd = dvd;
this.cd = cd;
this.projector = projector;
this.screen = screen;
this.lights = lights;
this.popper = popper;
}
public void watchMovie(String movie) {
System.out.println("Get ready to watch a movie...");
popper.on();
popper.pop();
lights.dim(10);
screen.down();
projector.on();
projector.wideScreenMode();
amp.on();
amp.setDvd(dvd);
amp.setSurroundSound();
amp.setVolume(5);
dvd.on();
dvd.play(movie);
}
public void endMovie() {
System.out.println("Shutting movie theater down...");
popper.off();
lights.on();
screen.up();
projector.off();
amp.off();
dvd.stop();
dvd.eject();
dvd.off();
}
public void listenToCd(String cdTitle) {
System.out.println("Get ready for an audiopile experence...");
lights.on();
amp.on();
amp.setVolume(5);
amp.setCd(cd);
amp.setStereoSound();
cd.on();
cd.play(cdTitle);
}
public void endCd() {
System.out.println("Shutting down CD...");
amp.off();
amp.setCd(cd);
cd.eject();
cd.off();
}
public void listenToRadio(double frequency) {
System.out.println("Tuning in the airwaves...");
tuner.on();
tuner.setFrequency(frequency);
amp.on();
amp.setVolume(5);
amp.setTuner(tuner);
}
public void endRadio() {
System.out.println("Shutting down the tuner...");
tuner.off();
amp.off();
}
}
출처: https://stevenjsmin.tistory.com/70 [Steven J.S Min's Blog]
퍼사드패턴 정리
서브시스템의 구성요소를 보호할 수 있다
클라이언트가 다루어야 할 객체 수가 줄어든다
서브시스템과 클라이언트 코드 간의 결합도를 줄일 수 있다. -> 최소 지식의 원칙
(정말 친한 사람하고만 이야기해라)
참고
https://jusungpark.tistory.com/23
https://mrw0119.tistory.com/70
https://lktprogrammer.tistory.com/42