큰 클래스 또는 밀접하게 관련된 클래스들의 집합을 두 개의 개별 계층구조(추상화 및 구현)로 나눈 후 각각 독립적으로 개발할 수 있도록 하는 구조 패턴
- Abstraction : 기능 계층의 최상위 클래스로, 기능을 정의한 인터페이스
- RefinedAbstraction : Abstraction 인터페이스를 확장한 클래스
- Implementor : Abstraction의 기능을 구현하기 위한 인터페이스
- ConcreteImplementor : Implementor 인터페이스를 구현한 클래스
tv와 radio를 리모컨으로 동작 가능하도록 기능을 확장한다고 가정해보자. 추상화(기능) 클래스를 확장하여 리모컨 동작 기능을 추가하고, 기존에 구현한 device와 연결해주어야 한다
[Device.java]
public interface Device {
public boolean isEnabled();
public void enable();
public void disable();
public int getVolume();
public void setVolume(int percent);
public int getChannel();
public void setChannel(int channel);
}
[Tv.java]
public class Tv implements Device {
boolean flag;
int volume;
int channel;
@Override
public boolean isEnabled() {
return flag;
}
@Override
public void enable() {
ystem.out.println("Tv On");
flag = true;
}
@Override
public void disable() {
ystem.out.println("Tv On");
flag = false;
}
@Override
public int getVolume() {
return volume;
}
@Override
public void setVolume(int percent) {
this.volume = percent;
System.out.println("Tv volume : " + volume);
}
@Override
public int getChannel() {
return channel;
}
@Override
public void setChannel(int channel) {
this.channel = channel;
System.out.println("Tv channel : " + channel);
}
}
[Radio.java]
public class Radio implements Device {
boolean flag;
int volume;
int channel;
@Override
public boolean isEnabled() {
return flag;
}
@Override
public void enable() {
System.out.println("Radio On");
flag = true;
}
@Override
public void disable() {
System.out.println("Radio On");
flag = false;
}
@Override
public int getVolume() {
return volume;
}
@Override
public void setVolume(int percent) {
this.volume = percent;
System.out.println("Radio volume : " + volume);
}
@Override
public int getChannel() {
return channel;
}
@Override
public void setChannel(int channel) {
this.channel = channel;
System.out.println("Radio channel : " + channel);
}
}
[RemoteController.java]
public class RemoteController {
Device device;
public RemoteController(Device device) {
this.device = device;
}
public void togglePower() {
if (device.isEnabled()) {
device.disable();
} else {
device.enable();
}
}
public void volumeDown() {
if (device.getVolume() - 10 < 0) {
device.setVolume(0);
} else {
device.setVolume(device.getVolume() - 10);
}
}
public void volumeUp() {
device.setVolume(device.getVolume() + 10);
}
public void channelDown() {
if (device.getChannel() - 1 < 0) {
device.setChannel(0);
} else {
device.setChannel(device.getChannel() - 1);
}
}
public void channelUp() {
device.setChannel(device.getChannel() + 1);
}
}
[AdvancedRemoteController.java]
public class AdvancedRemoteController extends RemoteController{
public AdvancedRemoteController(Device device) {
super(device);
}
public void mute() {
super.device.setVolume(0);
}
}
[Client.java]
public class Client {
public static void main(String[] args) {
Device tv = new Tv();
RemoteController tvRemoteController = new AdvancedRemoteController(tv);
tvRemoteController.togglePower();
tvRemoteController.togglePower();
tvRemoteController.volumeDown();
tvRemoteController.volumeUp();
tvRemoteController.channelUp();
tvRemoteController.channelDown();
System.out.println("===============");
Device radio = new Radio();
AdvancedRemoteController radioRemoteController = new AdvancedRemoteController(radio);
radioRemoteController.togglePower();
radioRemoteController.togglePower();
radioRemoteController.volumeDown();
radioRemoteController.volumeUp();
radioRemoteController.channelDown();
radioRemoteController.channelUp();
radioRemoteController.mute();
}
}