Adapter Pattern
특정 클래스 인터페이스를 클라이언트에게 요구하는 다른 인터페이스로 변환하는 패턴이다. 호환되지 않는 인터페이스를 사용하는 클라이언트를 그대로 활용할 수 있다.
Adpater 종류
객체 어댑터
- Composition으로 Adapter에게 요청을 전달한다.
- 어댑터 클래스와 그 서브 클래스에 대해서도 어댑터 역할이 가능하다.
- Composition을 사용하여 유연하다.
- 클라이언트는 Target에게 요청하고 있다고 생각한다.
- 어댑터는 Target을 대상으로 하는 요청에 Adaptee 클래스도 반응할 수 있게 한다.
- Adaptee는 Adapter에서 Target의 메소드 호출을 가로채서 Adaptee의 메소드 호출로 변환한다.
클래스 어댑터
- Target와 Adatper 모두 서브클래스로 만들어서 사용한다.
- 특정 어댑터 클래스에만 적용할 수 있다.
- 어댑터 전체를 다시 구현하지 않아도 된다.
- 클라이언트는 Target에게 요청하고 있다고 생각한다.
- Adpater는 Target 인터페이스를 구현하지만 메소드가 호출되었을 때 그 호출을 Adaptee 메소드 호출로 변환해준다.
- Adaptee는 Adapter를 통해 Target 인터페이스에 호출한 것을 받아 처리할 수 있다.
1장 오리 객체에 칠면조를 추가
Adaptee Interface
- Turkey(Target) 인터페이스를 추가
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
- Turkey를 Duck 객체로 바꿀 Adapter 클래스를 생성한다.
- Turkey 객체의 메서드를 Duck 객체의 메서드로 변환한다.
// 칠면조를 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();
Pacade Pattern
서브시스템에 있는 일련의 인터페이스를 통합 인터페이스로 묶는 패턴이다. 고수준 인터페이스도 정의하므로 서브시스템을 더 편리하게 사용할 수 있다.
- 단순화된 인터페이스를 제공하면서도, 클라이언트에게 필요로 한다면 시스템의 모든 기능의 사용이 가능하다.
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
- Client 대신 모든 서브 시스템 구성요소를 관리해 준다.
- 클라이언트의 친구는 Facade Class 하나 뿐이다. => 최소 지식 원칙
- 서브 시스템의 구성요소를 업그레이드해도 Client는 영향을 받지 않는다.
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();'Books > Head First Design Pattern' 카테고리의 다른 글
| [11장] Proxy Pattern (0) | 2024.05.24 |
|---|---|
| [8장] Template Method Pattern (0) | 2024.05.24 |
| [6장] Command Pattern (0) | 2024.05.24 |
| [5장] Singleton Pattern (0) | 2024.05.24 |
| [4장] Factory Pattern (0) | 2024.05.24 |