본문 바로가기

Design-Pattern

당신은 버튼만 누르면 됩니다! 퍼사드 패턴(facad pattern)

1. 퍼사드 패턴(facad pattern) 이란?

facad(퍼사드)는 외관이라는 뜻을 가지고 있습니다.

우리가 건물을 볼거나 이용할 때 건물의 기둥은 몇 개고 재질은 어떤 걸 사용했으며 벽돌이 몇 개인지 모두 알필요는 없습니다.

퍼사드 패턴도 이런 상황처럼 쓸 수 있습니다. 시스템의 일련의 인터페이스에 대한 통합된 인터페이스를 제공 퍼사드에서 고수준의 인터페이스를 정의하기 때문에 서브 시스템을 더 쉽게 사용할 수 있습니다.

 

즉 커피를 마시기 위해 생두를 가져와서 로스팅 -> 분쇄 -> 고압 추출 등의 작업을 할 필요 없이

원두를 넣고 버튼을 누르는 것만으로 커피가 완성되는 것과 같이요

퍼사드 패턴을 UML로 표현하면 다음과 같습니다.

퍼사드 UML 패턴

2. 퍼사드 패턴(facad pattern) 특징

퍼사드 패턴은 이럴 때 사용합니다.

1. 복잡한 서브 시스템에 대해서 간단한 인터페이스를 제공하고자 할 때

2. 서브클래스 간의 의존관계가 많을 경우 이에 대한 독립성을 올려주기 위해

 

퍼사드 패턴의 장점

1. 다뤄야 할 서브 클래스의 수를 줄여줍니다.

2. 서브 클래스 간의 결합도가 낮아집니다.

 

하지만 단점은 다음과 같습니다.

1. 서브클래스 간의 의존성은 낮아지지만 해당 의존성을 퍼사드 클래스 하나로 몰아넣었기 때문에 퍼사드와 서브 클래스의 결합도는 높아진다.

2. 레거시 코드가 많아질 수 있다.

 

3. 퍼사드 패턴(facad pattern) 구현

Amplifier

public class Amplifier {
	String description;
	Tuner tuner;
	StreamingPlayer player;
	public Amplifier(String description) { this.description = description; }
	public void on() { System.out.println(description + " on"); }
	public void off() { System.out.println(description + " off"); }
	public void setStereoSound() { System.out.println(description + " stereo mode on"); }
	public void setSurroundSound() { System.out.println(description + " surround sound on (5 speakers, 1 subwoofer)"); }
	public void setVolume(int level) { System.out.println(description + " setting volume to " + level); }
	public void setTuner(Tuner tuner) {
		System.out.println(description + " setting tuner to " + player);
		this.tuner = tuner;
	}
	public void setStreamingPlayer(StreamingPlayer player) {
		System.out.println(description + " setting Streaming player to " + player);
		this.player = player;
	}
	public String toString() { return description; }
}

CdPlayer

public class CdPlayer {
	String description;
	int currentTrack;
	Amplifier amplifier;
	String title;
	
	public CdPlayer(String description, Amplifier amplifier) {
		this.description = description;
		this.amplifier = amplifier;
	}
 	public void on() { System.out.println(description + " on"); }
	public void off() { System.out.println(description + " off"); }
	public void eject() {
		title = null;
		System.out.println(description + " eject");
	}
	public void play(String title) {
		this.title = title;
		currentTrack = 0;
		System.out.println(description + " playing \"" + title + "\"");
	}
	public void play(int track) {
		if (title == null) {
			System.out.println(description + " can't play track " + currentTrack + ", no cd inserted");
		} else {
			currentTrack = track;
			System.out.println(description + " playing track " + currentTrack);
		}
	}
	public void stop() {
		currentTrack = 0;
		System.out.println(description + " stopped");
	}
	public void pause() { System.out.println(description + " paused \"" + title + "\""); }
	public String toString() { return description; }
}

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();
	}
}

HomeTheaterTestDrive

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();
	}
}

PopcornPopper

public class PopcornPopper {
	String description;	
	public PopcornPopper(String description) { this.description = description; }
 	public void on() { System.out.println(description + " on"); }
	public void off() { System.out.println(description + " off"); }
	public void pop() { System.out.println(description + " popping popcorn!"); }
    public String toString() { return description; }
}

Projector

public class Projector {
	String description;
	StreamingPlayer player;
	public Projector(String description, StreamingPlayer player) {
		this.description = description;
		this.player = player;
	}
 	public void on() { System.out.println(description + " on"); }
	public void off() { System.out.println(description + " off"); }
	public void wideScreenMode() { System.out.println(description + " in widescreen mode (16x9 aspect ratio)"); }
	public void tvMode() { System.out.println(description + " in tv mode (4x3 aspect ratio)"); } 
    public String toString() { return description;}
}

Screen

public class Screen {
	String description;
	public Screen(String description) { this.description = description; }
	public void up() { System.out.println(description + " going up"); }
	public void down() { System.out.println(description + " going down"); }
	public String toString() { return description;}
}

StreamingPlayer

public class StreamingPlayer {
	String description;
	int currentChapter;
	Amplifier amplifier;
	String movie;
	public StreamingPlayer(String description, Amplifier amplifier) {
		this.description = description;
		this.amplifier = amplifier;
	}
	public void on() { System.out.println(description + " on"); }
	public void off() { System.out.println(description + " off"); }
	public void play(String movie) {
		this.movie = movie;
		currentChapter = 0;
		System.out.println(description + " playing \"" + movie + "\"");
	}
	public void play(int chapter) {
		if (movie == null) {
			System.out.println(description + " can't play chapter " + chapter + " no movie selected");
		} else {
			currentChapter = chapter;
			System.out.println(description + " playing chapter " + currentChapter + " of \"" + movie + "\"");
		}
	}

	public void stop() {
		currentChapter = 0;
		System.out.println(description + " stopped \"" + movie + "\"");
	}
	public void pause() { System.out.println(description + " paused \"" + movie + "\""); }
	public void setTwoChannelAudio() { System.out.println(description + " set two channel audio"); }
	public void setSurroundAudio() { System.out.println(description + " set surround audio"); }
	public String toString() { return description; }
}

TheaterLights

public class TheaterLights {
	String description;
	public TheaterLights(String description) { this.description = description; }
	public void on() { System.out.println(description + " on"); }
	public void off() { System.out.println(description + " off"); }
	public void dim(int level) { System.out.println(description + " dimming to " + level  + "%"); }
	public String toString() { return description;}
}

Tuner

public class Tuner {
	String description;
	Amplifier amplifier;
	double frequency;
	public Tuner(String description, Amplifier amplifier) { this.description = description; }
	public void on() { System.out.println(description + " on"); }
	public void off() { System.out.println(description + " off"); }
	public void setFrequency(double frequency) {
		System.out.println(description + " setting frequency to " + frequency);
		this.frequency = frequency;
	}
	public void setAm() { System.out.println(description + " setting AM mode"); }
	public void setFm() { System.out.println(description + " setting FM mode"); }
	public String toString() { return description;}
}