- 한 클래스가 두가지의 기능을 하는 경우, 예를 들어 도형에 관한 클래스 인데, shape 도, color 도 관리할 경우 종류가 많아지면 복잡해진다. 이럴때 shape 과 color 를 따로 빼서, shape 이 color 를 소유하는 식으로 하면 복잡도를 줄이고, single responsibility 를 지킬 수 있다.
- GoF 에서는 absctraction, implementation ( java 에서 말하는것이 아닌 concept 차원) 라고 설명하는거 같은데, 더 이해가 안된다.
- 예제에서는 Device 와 Remote 가 각각 interface 가 되고, Device 를 구현한 Radio, Tv 가 존재한다.
- 그리고 Remote 를 구현한 BasicRemote, 그걸 상속받은 AdvancedRemote 가 있는데, BasicRemote 를 보면 device 를 protected 필드로 가지고 있다.
- 이렇게 함으로써 Remote 대로, Device 대로, 각각 개발 따로 개발 할 수가 있는 것이다.
- Design pattern 을 살펴보며 느끼는건, 하나의 클래스는 하나만 관리하며, 서로 loose 하게 coupled 되어 있어야 한쪽이 바뀌었을때 타격이 적고, 그래야 다른 쪽을 신경쓰지 않고 개발 할 수 있으며, 점점 커지면 쪼개야 할 가능성이 높다는 것, 그래서 필요한만큼만 보여주고 나머지는 감추는 것 이다.
public interface Device {
int getVolume();
void setVolume(int percent);
int getChannel();
void setChannel(int channel);
}
public class Radio implements Device {
private boolean on = false;
private int volume = 30;
private int channel = 1;
@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;
}
}
public class Tv implements Device {
private boolean on = false;
private int volume = 30;
private int channel = 1;
@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;
}
}
public interface Remote {
void volumeDown();
void volumeUp();
void channelDown();
void channelUp();
}
public class BasicRemote implements Remote {
protected Device device;
public BasicRemote() {}
public BasicRemote(Device device) {
this.device = device;
}
@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);
}
}
public class AdvancedRemote extends BasicRemote {
public AdvancedRemote(Device device) {
super.device = device;
}
public void mute() {
System.out.println("Remote: mute");
device.setVolume(0);
}
}
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.channelUp();
System.out.println("Tests with advanced remote.");
AdvancedRemote advancedRemote = new AdvancedRemote(device);
advancedRemote.device.getVolume();
advancedRemote.mute();
}
}
Comments
Post a Comment