Facade Pattern

문지은·2022년 2월 10일
0

디자인패턴

목록 보기
2/4

어떤 상황에서 퍼사드 패턴이 필요할까?

홈 씨어터를 구축한다고 생각해보자.
DVD 플레이어, 프로젝트, 자동 스크린, 서라운드 음향, 팝콘 기계까지 갖춘 시스템을 구성했다고 하자. 그러면 각각에 해당하는 클래스가 필요하다. 그리고 영화를 보기 위해서 각각의 클래스를 조종하는 일련의 과정이 필요하다.

popper.on();
popper.pop();

lights.dim(10);

screen.down();

.
.
.

이런 상황에서 영화가 끝날 땐 이 상황을 반대로 해야할 수도 있고 작동 방법이 바뀌게 되면 해당 코드를 고쳐야 하는 문제가 생긴다.
이 때 퍼사드 패턴을 사용하면 간단한 인터페이스를 제공하여 복잡한 기능을 쉽게 사용하게 할 수 있다!

  1. 영화 시작, 영화 끄기 등등의 메서드가 담긴 퍼사드를 만든다
  2. 퍼사드 클래스에서 각 서브 시스템(홈 씨어터의 구성요소)의 메소드들을 호출하여 작업
  3. 클라이언트는 허사드의 메소드를 호출
  4. 이 때 퍼사드를 쓰더라도 서브 시스템에는 여전히 직접 접근 가능

퍼사드 패턴에 대한 의문점

  • 클라이언트에서 서브 시스템의 저수준 기능을 원한다면?
    퍼사드를 사용하지 않고 서브 시스템 클래스를 사용하면 된다.

  • 퍼사드에서 기능 추가 가능?
    서브 시스템 단순하게 활용하는 것 외에 새로운 기능 구현 가능

  • 한 서브 시스템에 대해 퍼사드를 한개만 만들 수 있는지?
    원하는 만큼 만들 수 있다.

  • 간단한 인터페이스 제공 외의 장점은?
    클라이언트와 서브 시스템 분리 가능.

  • 어댑터와 퍼사드 패턴의 차이점?
    클래스를 감싼다는 점에서 비슷하지만 용도가 다르다!
    감싸는 클래스의 개수는 상관없음 -> 어댑터가 여러 클래스를 감쌀수도, 퍼사드가 하나의 클래스만 감쌀수도 있다.
    어댑터 패턴 : 인터페이스를 클라이언트에서 필요로 하는 인터페이스로 변환
    퍼사드 패턴 : 서브 시스템에 대한 간단한 인터페이스를 제공하기 위함

HomeTheaterFacade 코드

public class HomeTheaterFacade {
	Amplifier amp;
	Tuner tuner;
	StreamingPlayer player;
	CdPlayer cd;
	Projector projector;
	TheaterLights lights;
	Screen screen;
	PopcornPopper popper;
 
	public HomeTheaterFacade(Amplifier amp, 
				 Tuner tuner, 
				 StreamingPlayer player, 
				 Projector projector, 
				 Screen screen,
				 TheaterLights lights,
				 PopcornPopper popper) {
 
		this.amp = amp;
		this.tuner = tuner;
		this.player = player;
		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.setStreamingPlayer(player);
		amp.setSurroundSound();
		amp.setVolume(5);
		player.on();
		player.play(movie);
	}
 
 
	public void endMovie() {
		System.out.println("Shutting movie theater down...");
		popper.off();
		lights.on();
		screen.up();
		projector.off();
		amp.off();
		player.stop();
		player.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();
	}
}

client 코드

public class HomeTheaterTestDrive {
	public static void main(String[] args) {
		Amplifier amp = new Amplifier("Amplifier");
		Tuner tuner = new Tuner("AM/FM Tuner", amp);
		StreamingPlayer player = new StreamingPlayer("Streaming Player", amp);
		CdPlayer cd = new CdPlayer("CD Player", amp);
		Projector projector = new Projector("Projector", player);
		TheaterLights lights = new TheaterLights("Theater Ceiling Lights");
		Screen screen = new Screen("Theater Screen");
		PopcornPopper popper = new PopcornPopper("Popcorn Popper");
 
		HomeTheaterFacade homeTheater = 
				new HomeTheaterFacade(amp, tuner, player, 
						projector, screen, lights, popper);
 
		homeTheater.watchMovie("Raiders of the Lost Ark");
		homeTheater.endMovie();
	}
}

퍼사드 패턴의 정의

어떤 서브 시스템의 일련의 인터페이스에 대한 통합된 인터페이스 제공 -> 퍼사드에서 고수준 인터페이스 정의 -> 서브 시스템 더 쉽게 이용 가능

최소 지식 원칙

퍼사드 패턴을 사용하면 최소 지식 원칙이라는 객체 지향 원칙을 지킬 수 있다.
최소 지식 원칙 : 상호 작용하는 클래스의 개수와 상호 작용 방식을 주의하여 의존성을 낮춰야 한다.

최소 지식 원칙을 지키면서 다른 객체에 영향력 행사하기

다음 네 종류의 객체 메소드만 호출하자

  • 객체 자체
  • 메소드에 매개변수로 전달된 객체
  • 그 메소드에서 생성하거나 인스턴스를 만든 객체
  • 그 객체에 속하는 구성 요소

최소 지식 원칙을 지킨 코드

public class Car {
	Engine engine;
    
    public void updateDashboadDisplay() {}
	
	public void start(Key key) {
    	Doors doors = new Doors();
        
        // 매개 변수로 전달된 객체
        boolean authorized = key.truns();
        
        if (authorized) {
        	// 객체의 구성요소
        	engine.start();
            // 객체 내의 메소드
            updateDashboardDisplay();
            // 직접 생성한 객체
            doors.lock();
        }
    }
	
}

최소 지식 원칙에 대한 의문점

  • 데메테르 법칙과의 관계?
    완전히 똑같은 말.

  • 최소 지식 원칙의 단점?
    래퍼 클래스를 많이 만들어서 시스템의 복잡도가 올라가거나 개발 시간이 늘어나고 성능이 떨어질 수 있다.

퍼사드와 최소 지식 원칙

퍼사드를 이용해서 클라이언트와 서브 시스템과의 관계를 끊어놨기 때문에 클라이언트와 서브 시스템은 각각 퍼사드와만 상호 작용할 수 있다.
-> 상호 작용하는 객체 최소화

profile
백엔드 개발자입니다.

0개의 댓글