레스트토랑을 생각해보면 손님이 들어와 주문서를 작성하면, 웨이터는 주문서를 받아 주방으로 전달한다. 웨이터 입장에선 주문을 받아 그대로 주방으로 전달하면 되기 때문에 고객이 어떤 주문을 했는지 주방에서 어떤 요리를 만드는지는 전혀 신경 쓸 필요가 없다.
커맨드 패턴이란, 요구사항을 객체로 캡슐화 할 수 있는 디자인 패턴으로 작업을 요청한 쪽과 처리하는 쪽을 분리할 수 있다.
집안에서 공용으로 쓰는 리모콘이 있다고 가정하자. 이 리모콘을 통해 문을 열고 닫을 수 있으며, 불을 키고 끌수있고, 커튼을 열고 닫을 수 있다. 여기서 요구사항은 리모콘을 통해 요청되는 작업들이며 이 작업들을 캡슐화하여 요청작업과 실행작업을 분리시킨다.
간단한 예로 불을 켜는 리모콘 소스를 보자. (예시를 위한 코드지, 실제 동작하지 않음)
public interface Command {
public void execute();
}
public class LightOnCommand implements Command {
Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.on();
}
}
public class SimpleRemoteControl {
Command slot;
public SimpleRemoteControl() {}
public void setCommand(Command command) {
slot = command;
}
public void putButton() {
slot.execute();
}
}
SimpleRemoteControl 클래스는 Command slot 변수를 가지며, setCommand 메소드를 통해 slot 변수를 set 할 수 있다. Command 변수로는 불을 키고끄고, 문을 열고 닫는 등 다양한 명령들이 들어올 수 있다.Command 인터페이스를 구현한 클래스(여기선 LightOnCommand)들이 실행작업을 구현하며, 요청작업은 SimpleRemoteControl의 setCommand를 호출한 쪽에서 명령을 요청하므로 커맨드 패턴처럼 분리된 걸 알 수 있다.
위 구조로 확장을 하자. 불을 켜고 끄고, 문을 열고 닫고, 에어콘을 키고 끄는 형태를 다이어그램으로 보면 아래와 같다.
집 주인의 다양한 요청(불, 에어콘, 문, 커튼 등등)의 구현은 Command 인터페이스를 구현하는 클래스들에서 맡고 있다. 요청은 SimpleRemoteControl 클래스에서 SetCommand로 수행한다. SimpleRemoteControl은 집 주인의 요청에 대해 신경쓸필요가 없으며 execute()로 실제 어떤 행동이 수행되는지 알 필요가 없다.
댓글 없음:
댓글 쓰기