Facade

2 minute read

Facade Pattern


퍼사드 패턴이란?

어떤 서브시스템의 일련의 인터페이스에 대한 통합된 인터페이스를 제공

퍼사드에서 고수준 인터페이스를 정의하기 때문에 서브시스템을 더 쉽게 사용할 수 있음

클래스 패키지에 인터페이스를 제공하기 위해 사용


간단한 예를 들어보자


img

본래 client는 각각의 System을 알고 일일이 접근해야 했다. -> 커플링

img

하지만 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객체를 알 필요가 없다!

퍼사드의 메서드만 알면 된다

+ 기능이 추가되더라도 클라이언트는 아무런 변경이 없다

image.png


비슷한 예시로 참고할 수 있는 것(홈시어터 컴포넌트 조작)


 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]

 

퍼사드패턴 정리

서브시스템의 구성요소를 보호할 수 있다

클라이언트가 다루어야 할 객체 수가 줄어든다

서브시스템과 클라이언트 코드 간의 결합도를 줄일 수 있다. -> 최소 지식의 원칙

(정말 친한 사람하고만 이야기해라)

image.png


참고

https://jusungpark.tistory.com/23

https://mrw0119.tistory.com/70

https://lktprogrammer.tistory.com/42

Updated: