커맨드 패턴

객체지향 모델링은 실 세계를 모델링 하는 것 처럼 소프트웨어를 모델링 하는 것.
레스트토랑을 생각해보면 손님이 들어와 주문서를 작성하면, 웨이터는 주문서를 받아 주방으로 전달한다. 웨이터 입장에선 주문을 받아 그대로 주방으로 전달하면 되기 때문에 고객이 어떤 주문을 했는지 주방에서 어떤 요리를 만드는지는 전혀 신경 쓸 필요가 없다.

커맨드 패턴이란, 요구사항을 객체로 캡슐화 할 수 있는 디자인 패턴으로 작업을 요청한 쪽과 처리하는 쪽을 분리할 수 있다.

집안에서 공용으로 쓰는 리모콘이 있다고 가정하자. 이 리모콘을 통해 문을 열고 닫을 수 있으며, 불을 키고 끌수있고, 커튼을 열고 닫을 수 있다. 여기서 요구사항은 리모콘을 통해 요청되는 작업들이며 이 작업들을 캡슐화하여 요청작업과 실행작업을 분리시킨다.

간단한 예로 불을 켜는 리모콘 소스를 보자. (예시를 위한 코드지, 실제 동작하지 않음)

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()로 실제 어떤 행동이 수행되는지 알 필요가 없다.







댓글 없음:

댓글 쓰기