헤드퍼스트 디자인패턴 Chapter7 - 퍼사드 패턴

헤드퍼스트 디자인패턴

  • 본 책을 읽고 책의 내용을 간략하게 정리한 글입니다.

Chapter 7. 적응시키기 - 퍼사드 패턴

예제 프로젝트 - 홈시어터 만들기

  • 영화나 TV 시리즈를 몰아볼 수 있는 홈시어터를 구축해보자.
  • 홈시어터에는 스트리밍 플레이어, 프로젝터, 자동 스크린, 자동 조명, 서라운드 음향, 팝콘 기계가 갖춰져 있다고 한다.
  • 어떤 클래스와 어떤 메서드가 필요한 지 살펴보기
// 팝콘 기계
popper.on();
popper.pop();

// 조명
lights.dim(10);

// 스크린
screen.down();

// 프로젝터
projector.on();
projector.setInput(player);
projector.wideScreenMode();

// 서라운드 음향 (앰프)
amp.on();
amp.setDvd(player);
amp.setSurroundSound();
amp.setVolumn(5);

// 스트리밍 플레이어
player.on();
player.play(movie);
  • 클래스가 6개나 필요하며, 영화를 보거나 다 보고 난 후 수행해야 할 동작들이 너무 복잡하다는 문제가 있다.
  • 이런 복잡한 일을 간단하게 처리할 수 있는 게 바로 퍼사드 패턴

퍼사드 작동 원리 알아보기

  1. 홈시어터 시스템용 퍼사드로 watchMovie() 와 같은 몇 가지 간단한 메서드만 들어있는 HomeTheaterFacade 클래스를 만든다.
  2. 퍼사드 클래스는 홈시어터 구성 요소를 하나의 서브시스템으로 간주하고, watchMovie() 메서드는 서브시스템의 메서드를 호출하여 필요한 작업을 처리한다.
  3. 클라이언트는 서브시스템이 아닌 퍼사드에 있는 메서드만 호출한다.
  4. 퍼사드를 사용하더라도 서브시스템에 접근 가능하다.

홈시어터 퍼사드 작성하기

public class HomeTheaterFacade {
	Amplifier amp;
	StreamingPlayer player;
	Projector projector;
	TheaterLights lights;
	Screen screen;
	PopcornPopper popper;
	
	public HomeTheaterFacade(Amplifier amp,
                             StreamingPlayer player,
                             Projector projector,
                             TheaterLights lights,
                             Screen screen,
                             PopcornPopper popper) {
		this.amp = amp;
		this.player = player;
		this.projector = projector;
		this.lights = lights;
		this.screen = screen;
		this.popper = popper;
    }
	
	public void watchMovie(String movie) {
		System.out.println("영화 시청 준비");
		popper.on();
		popper.pop();
		lights.dim(10);
		screen.down();
		projector.on();
		projector.wideScreenMode();
		amp.on();
		amp.setStreamingPlayer(player);
		amp.setSurroundSound();
		amp.setVolume(5);
		player.on();
		player.play(movie);
    }
	
	public void endMovie() {
		System.out.println("홈시어터를 끄는 중");
		popper.off();
		lights.on();
		screen.up();
		projector.off();
		amp.off();
		player.stop();
		player.off();
    }
}

퍼사드 패턴의 정의

  • 퍼사드 패턴은 서브시스템에 있는 일련의 인터페이스를 통합 인터페이스로 묶어주며, 고수준 인터페이스도 정의하므로 서브시스템을 더 편리하게 사용할 수 있다.

최소 지식 원칙

디자인 원칙 6

  • 진짜 절친에게만 이야기해야 한다.
  • 시스템을 디자인할 때 어떤 객체든 그 객체와 상호작용하는 클래스의 개수와 상호작용 방식에 주의를 기울여야 한다.
  • 이 원칙을 잘 따르면 여러 클래스가 복잡하게 얽혀 있어서, 시스템의 한 부분을 변경했을 때 다른 부분까지 줄줄이 고쳐야 하는 상황을 미리 방지할 수 있다.

의존하지 않고 다른 객체에 영향력 행사하기

  • 다음 4개의 가이드라인을 제시한다.
    1. 객체 자체
    2. 메서드에 매개변수로 전달된 객체
    3. 메서드를 생성하거나 인스턴스를 만든 객체
    4. 객체에 속하는 구성 요소
  • 원칙을 따르지 않은 경우
    public float getTemp() {
      Thermometer thermometer = station.getThermometer();
      return thermometer.getTemperature();
    }
    
  • 원칙을 따르는 경우
    public float getTemp() {
      return station.getTemperature();
    }
    

최소 지식 원칙 예제 클래스

public class Car {
	Engine engine;
	// 기타 인스턴스 변수
	
	public Car() {
		// 엔진 초기화 등 처리
	}
	
	public void start(Key key) {
		Doors doors = new Doors();
		boolean authorized = key.turns();   // 매개변수로 전달받은 객체의 메서드는 호출해도 됩니다.
		if (authorized) {
			engine.start();
			updateDashboardDisplay();   // 객체 내에 있는 메서드는 호출해도 됩니다.
			doors.lock();   // 직접 생성하거나 인스턴스를 만든 객체의 메서드는 호출해도 됩니다.
		}
    }
	
	public void updateDashboardDisplay() {
		// 디스플레이 업데이트
    }
}

퍼사드 패턴과 최소 지식 원칙

  • 클라이언트는 홈시어터 퍼사드 하나에만 의존한다.
  • 홈시어터 구성을 업데이트해도 클라이언트는 아무 영향을 받지 않는다.
  • 서브시스템에서도 서로 얽혀 있는 객체가 많아 시스템이 복잡해진다면 퍼사드를 추가하는 것도 방법이다.