특정 클래스 인터페이스를 클라이언트에게 요구하는 다른 인터페이스로 변환하는 패턴이다. 호환되지 않는 인터페이스를 사용하는 클라이언트를 그대로 활용할 수 있다.
Adaptee Interface
public interface Turkey {
public void gobble();
public void fly();
}
Concrete Class
public class WildTurkey implements Turkey {
public void gobble() {
System.out.println("Gobble gobble");
}
public void fly() {
System.out.println("I'm flying a short distance");
}
}
Adapter Class
// 칠면조를 Duck으로 변환하기 위한 Adapter
public class TurkeyAdapter implements Duck {
Turkey turkey; // Turkey 객체
public TurkeyAdapter(Turkey turkey) {
this.turkey = turkey; // 객체를 전달받음
}
// Turkey 객체의 메서드를 Duck 객체의 메서드로 변환
public void quack() {
turkey.gobble(); // gobble을 quack으로
}
public void fly() {
for(int i=0; i < 5; i++) {
turkey.fly();
}
}
}
Test.java
public class DuckTestDrive {
public static void main(String[] args) {
Turkey turkey = new WildTurkey(); // Turkey 객체 생성
Duck turkeyAdapter = new TurkeyAdapter(turkey); // 어댑터 생성
// Turkey 객체 수행
System.out.println("The Turkey says...");
turkey.gobble();
turkey.fly();
// Turkey 객체를 Duck 형태로 바꿨을 때 실행 결과
System.out.println("\nThe TurkeyAdapter says...");
turkeyAdapter.quack();
turkeyAdapter.fly();
서브시스템에 있는 일련의 인터페이스를 통합 인터페이스로 묶는 패턴이다. 고수준 인터페이스도 정의하므로 서브시스템을 더 편리하게 사용할 수 있다.
OO 원칙
- 최소 지식 원칙: 객체 사이의 상호작용은 될 수 있으면 아주 가까운 친구 사이에서만 허용한다. 여러 클래스가 복잡하게 얽혀있어 시스템의 한 부분을 변경했을 때, 다른 부분까지 수정해야하는 것을 미리 방지해야 한다.
최소 지식 원칙 4가지 가이드 라인
- 객체 자체
- 메소드에 매개변수로 전달된 객체
- 메소드를 생성하거나 인스턴스를 만든 객체
- 객체에 속하는 구성요소
public float getTemp() {
// station으로 부터 thermometer 객체를 받은 다음, 그 객체의 getThermometer 메서드를 직접 호출
Thermometer thermometer = station.getThermometer();
return thermometer.getThermometer();
}
public float getTemp() {
// thermometer에게 요청을 전달하는 메서드를 station 클래스에 추가
return station.getThermometer();
}
Facade Class
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();
}
}
Test.java
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();