Command

1 minute read

Command Pattern

What’s Command Pattern ?

  • 작동(Action), 트랜잭션(Transaction)으로도 불림
  • 요청 자체를 캡슐화하는 것입니다. 이를 통해 요청이 서로 다른 사용자를 매개변수로 만들고, 요청을 대기시키거나 로깅하며, 되돌릴 수 있는 연산을 지원합니다.

Purpose

  • 용도

    • 요구사항을 객체로 캡슐화 할 수 있으며, 매개변수를 써서 여러가지 다른 요구사항을 집어넣을 수 도 있습니다. 또한 요청 내역을 큐에 저장하거나 로그로 기록할 수도 있으며, 작업취소 기능도 지원이 가능합니다.

      1. 자리에 앉아서 주문서를 적어서, 웨이터에게 전달합니다.
      2. 웨이터는 주방에 가서 손님에게 받은 주문서를 전달합니다.
      3. 주방장이 받은 주문대로 요리를 만듭니다.

      주문서는 받은 주문을 캡슐화 하는 역할을 합니다. 웨이터는 주문서의 내용을 전혀 몰라도 됩니다. 그냥 이 주문서를 가져다가 그대로 주방에 가져다 주고 “주방장님 주문 들어왔어요!!” 하고 주방장을 호출 하면 됩니다. 즉 주방장과 웨이터는 완전히 분리되어 있다는 것이죠. (물론 현실에서의 웨이터는 알아야 되겠죠?)

      요리법에 대한 정보는 모두 주방장에게 있고, 주방장은 받은 주문서에 적혀 있는 대로 요리를 하면 되니, 웨이터와 주방장이 직접 대면해서 무언가를 할 필요가 없습니다.

    식당 주문 시스템 커맨드 패턴
    손님 Client
    웨이터 Invoker
    주문을 받는 행위 setCommand()
    주문서 Command
    주문을 주방장에게 전달하여 요리를 요청하는 행위 execute()
    주방장 Receiver

UML

Command Design Pattern Class Diagram.png

​ 커맨드 패턴의 기본 UML 다이어그램

command uml.PNG

​ 커맨드 패턴으로 설계한 리모컨 UML 다이어그램 및 main 메소드 코드


Example

// 1. Command 인터페이스 정의하기
// 커맨드 객체에는 execute() 메소드 하나밖에 지원 하지 않습니다. 하지만 나중에 작업 취소 기능을 위한 	메소드를 추가할 수 있습니다.
public interface Command {
 
    public void execute();
    
}
// 2. Receiver 객체 (여기서는 전등) 만들기
public class Light {
 
    public void on() { System.out.println("전등 켜짐"); }
    public void off() { System.out.println("전등 꺼짐"); }
    
}
// 3. 인터페이스를 상속받는 커맨드 객체 만들기
public class LightOnCommand implements Command {
    Light light; 
        
    public LightOnCommand(Light light) {
        this.light = light;
    }
 
    public void execute() {
        light.on();
    }
}

// 4. 인보커 객체 만들기
// 커맨드 객체를 저장하는 인보커 객체를 만듭니다. 
// 클라이언트 객체에서 buttonPressed() 메소드를 호출하면 저장된 커맨드 객체에서 execute() 메소드를 호출하게 됩니다. 
public class SimpleRemoteControl {
    
    Command slot;
 	
    public SimpleRemoteControl() {}
    
    public void setCommand(Command command) {slot = command;}
    
    public void buttonPressed() { slot.execute(); }
 
}
// 5. 클라이언트 객체 만들기 
// 사용자는 커맨드 객체를 만들어, 인보커 객체인 SimpleRemoteControl 객체로 setCommand() 메소드를 통해 전달합니다. 
// 그리고 클라이언트 객체가 buttonPressed() 메소드를 호출하면 execute() 메소드가 호출되면서, 전등의 on()메소드가 연달아 호출 되는 것이죠. 
// 그렇게 되면 콘솔에 "전등 켜짐" 이라고 나타나게 됩니다. 
public class RemoteControlTest {
    public static void main(String[] args) {
        SimpleRemoteControl remote = new SimpleRemoteControl();
        Light light = new Light();
        LightOnCommand lightOn = new LightOnCommand(light);
        
        remote.setCommand(lightOn);
        remote.buttonPressed();
    }
}

참고

https://gdtbgl93.tistory.com/23

Updated: