13. Bridge Pattern
2021. 11. 14. 22:14ㆍComputer Sciences/Design Patterns
문제
TV를 작동시키는 리모컨은 여러 제조사가 있다. 그래서 TV를 모든 리모컨으로 동작시키기 위해서는 리모컨을 인터페이스화 하고 TV를 컴포지션하여 사용할 수 있었다. 그런데 이젠 TV 제조사가 많아졌다. 기존에는 삼성이 모든 TV를 만들었지만 이젠 LG도 TV를 생산한다고 한다. 이를 어떻게 풀어야 할까?
해결 방안
이 문제를 해결하는 방법은 간단하다. 리모컨에서 한 것처럼 TV도 인터페이스화하고 리모컨에서는 TV 인터페이스를 컴포지션하면 된다. 클래스 다이어그램으로 나타내면 다음과 같다.
그리고 RemoteControl과 TV의 관계를 브릿지 관계라고 한다.
Java 코드로 구현하면 다음과 같다.
public class Client {
public static void main(String[] args) {
TVFactory tvFactory = new TVFactory();
SpecialRemote remoteSamsung = new SpecialRemote(tvFactory);
System.out.println("리모컨을 사용하기 전에 TV를 설정하세요.");
remoteSamsung.setTV("Samsung");
remoteSamsung.on();
remoteSamsung.up();
remoteSamsung.down();
remoteSamsung.off();
GenericRemote remoteLG = new GenericRemote(tvFactory);
System.out.println("리모컨을 사용하기 전에 TV를 설정하세요.");
remoteLG.setTV("LG");
remoteLG.on();
remoteLG.setNextChannel();
remoteLG.setPrevChannel();
remoteLG.off();
}
}
public abstract class RemoteControl {
TV tv;
TVFactory tvFactory;
public RemoteControl(TVFactory tvFactory) {
this.tvFactory = tvFactory;
}
public void on() {
this.tv.on();
}
public void off() {
this.tv.off();
}
public void setChannel(int channel) {
tv.tuneChannel(channel);
}
public int getChannel() {
return tv.getChannel();
}
public void setTV(String type) {
try {
tv = tvFactory.getTV(type);
} catch (Exception e) {
System.out.println(e);
}
}
}
public class GenericRemote extends RemoteControl {
public GenericRemote(TVFactory tvFactory) {
super(tvFactory);
}
public void setNextChannel() {
int channel = this.getChannel();
this.setChannel(channel+1);
}
public void setPrevChannel() {
int channel = this.getChannel();
this.setChannel(channel-1);
}
}
public class SpecialRemote extends RemoteControl {
public SpecialRemote(TVFactory tvFactory) {
super(tvFactory);
}
public void up() {
int channel = this.getChannel();
this.setChannel(channel+1);
}
public void down() {
int channel = this.getChannel();
this.setChannel(channel-1);
}
}
public abstract class TV {
abstract void on();
abstract void off();
abstract void tuneChannel(int channel);
abstract int getChannel();
}
public class LG extends TV {
int station = 1;
public void on() {
System.out.println("Turning on the LG TV");
}
public void off() {
System.out.println("Turning off the LG TV");
}
public void tuneChannel(int station) {
this.station = station;
System.out.println("Set the LG TV station to " + this.station);
}
public int getChannel() {
return station;
}
}
public class Samsung extends TV {
int channel = 0;
public void on() {
System.out.println("Turning on the Samsung TV");
}
public void off() {
System.out.println("Turning off the Samsung TV");
}
public void tuneChannel(int channel) {
this.channel = channel;
System.out.println("Set the Samsung TV Channel to " + this.channel);
}
public int getChannel() {
return channel;
}
}
public class TVFactory {
public TV getTV(String type) throws Exception {
if (type.equals("LG")) {
return new LG();
} else if (type.equals("Samsung")) {
return new Samsung();
} else {
throw new Exception("Invalid TV Type");
}
}
}
장단점
장점
- 구상 클래스와 인터페이스를 완전히 결합하지 않았기 때문에 구현과 추상화된 부분을 분리시킬 수 있다.
- 추상화된 부분과 실제 구현 부분을 독립적으로 확장할 수 있다.
- 추상화된 부분을 구현한 구상 클래스를 바꿔도 클라이언트 측에는 영향을 끼치지 않는다.
단점
- 디자인이 복잡해진다.
활용법
- 여러 플랫폼에서 사용해야 할 그래픽스 및 윈도우 처리 시스템에서 유용하게 사용된다.
- 인터페이스와 실제 구현부를 서로 다른 방식으로 변경해야 하는 경우에 유용하게 사용된다.
'Computer Sciences > Design Patterns' 카테고리의 다른 글
Prototype Pattern (0) | 2021.12.11 |
---|---|
14. Chain of Responsibility Pattern (0) | 2021.11.14 |
12. State Pattern (0) | 2021.10.15 |
11. Composite Pattern (0) | 2021.10.15 |
10. Iterator Pattern (0) | 2021.10.15 |