[디자인 패턴] 커맨드(Command) 패턴
커맨드 패턴
커맨드 패턴이란, 요청을 객체의 형태로 캡슐화 해서 사용자가 보낸 요청을 나중에 이용하도록 하는 패턴이다. 호출과 수신자 클래스 사이의 의존성이 제거 되며, 이벤트가 발생했을 때 실행될 기능이 다양하지만, 변경이 필요한 경우 재사용 할 수 있어 유용하다.
구현
리모콘은 실행활에서 자주 사용한다. 해당 버튼이 눌렸다는 이벤트가 있지만, 각각 하는 역할이 다르다.
public interface Command {
public void run();
}
커맨드를 실행시킨다는 인터페이스가 있다.
public class VolumeUpCommand implements Command {
private Speaker speaker;
public VolumeUpCommand(Speaker speaker) {
this.speaker = speaker;
}
@Override
public void run() {
speaker.volumeUp();
}
}
public class VolumeDownCommand implements Command {
private Speaker speaker;
public VolumeDownCommand(Speaker speaker) {
this.speaker = speaker;
}
@Override
public void run() {
speaker.volumeDown();
}
}
public class Speaker {
public void volumeUp() {
System.out.println("볼륨이 증가했다.");
}
public void volumeDown() {
System.out.println("볼륨이 감소했다.");
}
}
볼륨을 증가시키거나 볼륨을 감소하도록 명령할 수 있기 때문에 Command 를 구현한 증가 커맨드와 감소 커맨드가 있고, 실질적으로 메소드는 스피커 클래스에 구현한다. 이제 리모콘에 버튼이 눌렸을 때 커맨드를 수행하도록 구성하자.
public class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.run();
}
}
실제로 리모콘 조작을 한다고 가정하면…
public class Client {
public static void main(String[] args) {
Speaker speaker = new Speaker();
Command volumeUpCommand = new VolumeUpCommand(speaker);
Command volumeDownCommand = new VolumeDownCommand(speaker);
RemoteControl remoteControl = new RemoteControl();
remoteControl.setCommand(volumeUpCommand);
remoteControl.pressButton();
remoteControl.setCommand(volumeDownCommand);
remoteControl.pressButton();
}
}
여기서 setCommand → pressButton 과정이 반복되기 때문에 별도로 묶어두는 메소드 등을 추가할 수 있을 것 같다.
그냥 if 나 switch-case 로 구현한 것과 다른점?
조건 분기와 다른 점은 새로운 기능을 추가할 때 분기에 하나씩 추가해야하지만, 커맨드 패턴의 경우 새로운 클래스만 추가하면 되기 때문에 OCP에 위배되지 않는다. 또한, 캡슐화를 통해서 실제 해당 커맨드를 호출하는 부분에서는 세부 내용을 모르더라도 작동한다는 장점이 있다.
Leave a comment