
자바로 작성된 브리지
브리지는 구조 디자인 패턴입니다. 이 패턴은 비즈니스 로직 또는 거대한 클래스를 독립적으로 개발할 수 있는 별도의 클래스 계층구조들로 나눕니다.
종종 추상화라고 불리는 이러한 계층구조 중 하나는 두 번째 계층구조의 객체(구현)에 대한 참조를 얻습니다. 추상화의 호출들 일부(때로는 대부분)를 구현 객체에 위임할 수 있습니다. 모든 구현은 공통 인터페이스를 가지므로 추상화 내에서 상호 교환할 수 있습니다.
복잡도:
인기도:
사용 예시들: 브리지 패턴은 크로스 플랫폼 앱들을 처리할 때, 여러 유형의 데이터베이스 서버를 지원할 때 또는 특정 종류의 여러 API 제공자(예: 클라우드 플랫폼, 소셜 네트워크 등)와 작업할 때 특히 유용합니다.
식별법: 브리지는 일부 제어 개체가 해당 개체가 의존하는 여러 다른 플랫폼들과 명확하게 구분됩니다.
장치와 리모컨 사이의 브리지
이 예시는 리모컨 클래스들과 그들이 조절하는 장치들 사이의 분리를 보여줍니다.
리모컨들은 추상화로 작동하고, 장치들은 그들의 구현으로 작동합니다. 공통 인터페이스 덕분에 같은 리모컨들은 다른 장치들과 작동할 수 있고 그 반대의 경우도 가능합니다.
브리지 패턴은 반대 계층구조의 코드를 건드리지 않고도 클래스들을 변경하거나 새로운 클래스들을 생성할 수 있도록 합니다.
devices
devices/Device.java: 모든 장치에 대한 공통 인터페이스
package refactoring_guru.bridge.example.devices;
public interface Device {
boolean isEnabled();
void enable();
void disable();
int getVolume();
void setVolume(int percent);
int getChannel();
void setChannel(int channel);
void printStatus();
}
devices/Radio.java: 라디오
package refactoring_guru.bridge.example.devices;
public class Radio implements Device {
private boolean on = false;
private int volume = 30;
private int channel = 1;
@Override
public boolean isEnabled() {
return on;
}
@Override
public void enable() {
on = true;
}
@Override
public void disable() {
on = false;
}
@Override
public int getVolume() {
return volume;
}
@Override
public void setVolume(int volume) {
if (volume > 100) {
this.volume = 100;
} else if (volume < 0) {
this.volume = 0;
} else {
this.volume = volume;
}
}
@Override
public int getChannel() {
return channel;
}
@Override
public void setChannel(int channel) {
this.channel = channel;
}
@Override
public void printStatus() {
System.out.println("------------------------------------");
System.out.println("| I'm radio.");
System.out.println("| I'm " + (on ? "enabled" : "disabled"));
System.out.println("| Current volume is " + volume + "%");
System.out.println("| Current channel is " + channel);
System.out.println("------------------------------------\n");
}
}
devices/Tv.java: 텔레비전
package refactoring_guru.bridge.example.devices;
public class Tv implements Device {
private boolean on = false;
private int volume = 30;
private int channel = 1;
@Override
public boolean isEnabled() {
return on;
}
@Override
public void enable() {
on = true;
}
@Override
public void disable() {
on = false;
}
@Override
public int getVolume() {
return volume;
}
@Override
public void setVolume(int volume) {
if (volume > 100) {
this.volume = 100;
} else if (volume < 0) {
this.volume = 0;
} else {
this.volume = volume;
}
}
@Override
public int getChannel() {
return channel;
}
@Override
public void setChannel(int channel) {
this.channel = channel;
}
@Override
public void printStatus() {
System.out.println("------------------------------------");
System.out.println("| I'm TV set.");
System.out.println("| I'm " + (on ? "enabled" : "disabled"));
System.out.println("| Current volume is " + volume + "%");
System.out.println("| Current channel is " + channel);
System.out.println("------------------------------------\n");
}
}
remotes
remotes/Remote.java: 모든 리모컨에 대한 공통 인터페이스
package refactoring_guru.bridge.example.remotes;
public interface Remote {
void power();
void volumeDown();
void volumeUp();
void channelDown();
void channelUp();
}
remotes/BasicRemote.java: 기초 리모콘
package refactoring_guru.bridge.example.remotes;
import refactoring_guru.bridge.example.devices.Device;
public class BasicRemote implements Remote {
protected Device device;
public BasicRemote() {}
public BasicRemote(Device device) {
this.device = device;
}
@Override
public void power() {
System.out.println("Remote: power toggle");
if (device.isEnabled()) {
device.disable();
} else {
device.enable();
}
}
@Override
public void volumeDown() {
System.out.println("Remote: volume down");
device.setVolume(device.getVolume() - 10);
}
@Override
public void volumeUp() {
System.out.println("Remote: volume up");
device.setVolume(device.getVolume() + 10);
}
@Override
public void channelDown() {
System.out.println("Remote: channel down");
device.setChannel(device.getChannel() - 1);
}
@Override
public void channelUp() {
System.out.println("Remote: channel up");
device.setChannel(device.getChannel() + 1);
}
}
remotes/AdvancedRemote.java: 고급 리모콘
package refactoring_guru.bridge.example.remotes;
import refactoring_guru.bridge.example.devices.Device;
public class AdvancedRemote extends BasicRemote {
public AdvancedRemote(Device device) {
super.device = device;
}
public void mute() {
System.out.println("Remote: mute");
device.setVolume(0);
}
}
Demo.java: 클라이언트 코드
package refactoring_guru.bridge.example;
import refactoring_guru.bridge.example.devices.Device;
import refactoring_guru.bridge.example.devices.Radio;
import refactoring_guru.bridge.example.devices.Tv;
import refactoring_guru.bridge.example.remotes.AdvancedRemote;
import refactoring_guru.bridge.example.remotes.BasicRemote;
public class Demo {
public static void main(String[] args) {
testDevice(new Tv());
testDevice(new Radio());
}
public static void testDevice(Device device) {
System.out.println("Tests with basic remote.");
BasicRemote basicRemote = new BasicRemote(device);
basicRemote.power();
device.printStatus();
System.out.println("Tests with advanced remote.");
AdvancedRemote advancedRemote = new AdvancedRemote(device);
advancedRemote.power();
advancedRemote.mute();
device.printStatus();
}
}
OutputDemo.txt: 실행 결과
Tests with basic remote.
Remote: power toggle
------------------------------------
| I'm TV set.
| I'm enabled
| Current volume is 30%
| Current channel is 1
------------------------------------
Tests with advanced remote.
Remote: power toggle
Remote: mute
------------------------------------
| I'm TV set.
| I'm disabled
| Current volume is 0%
| Current channel is 1
------------------------------------
Tests with basic remote.
Remote: power toggle
------------------------------------
| I'm radio.
| I'm enabled
| Current volume is 30%
| Current channel is 1
------------------------------------
Tests with advanced remote.
Remote: power toggle
Remote: mute
------------------------------------
| I'm radio.
| I'm disabled
| Current volume is 0%
| Current channel is 1
------------------------------------