실행될 기능을 캡슐화 해서 재사용성을 높이는 패턴이다.
커맨드패턴을 이용하면 요구사항대로 객체를 캡슐화 할 수 있으며, 매게변수를 써서 여러가지 다른 요구사항을 집어넣을 수 있다.
커맨드패턴은
명령을 주는 클라이언트
이를 받는 커맨드
이를 세팅하는 인보커
최종적으로 메소드를 호출하는 리시버
로 구성되어 있다.
리시버를 캡슐화할 수 있고, undo를 통해 복구하거나 로그를 남겨 작업을 다시 시도하기가 쉽다.
출처
클라이언트
package command;
public class RemoteControlTest {
public static void main(String[] args) {
SimpleRemoteControl remote = new SimpleRemoteControl();
Light light = new Light();
GarageDoor garageDoor = new GarageDoor();
LightOnCommand lightOn = new LightOnCommand(light);
GarageDoorOpenCommand garageDoorOpenCommand = new GarageDoorOpenCommand(garageDoor);
remote.setCommand(lightOn);
remote.buttonWasPressed();
remote.setCommand(garageDoorOpenCommand);
remote.buttonWasPressed();
}
}
인터페이스
package command;
public interface Command {
public void execute();
}
인보커
package command;
public class SimpleRemoteControl {
Command slot;
public SimpleRemoteControl() {}
public void setCommand(Command command) {
slot = command;
}
public void buttonWasPressed() {
slot.execute();
}
}
커맨드 구현
package command;
public class LightOnCommand implements Command{
Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
}
리시버
package command;
public class Light {
void on() {
System.out.println("Light ON");
}
void off() {
System.out.println("Light OFF");
}
}
이러한 구성으로 이루어져있다.
클라이언트에서 인보커 LightOnCommand에 lighton을 set하고 이를 실행하면 reciever light클래스의 on메서드가 실행되는 방식이다.
package command;
import java.util.Arrays;
public class RemoteControl {
Command[] onCommands;
Command[] offCommands;
public RemoteControl() {
onCommands = new Command[7];
offCommands = new Command[7];
Command noCommand = new NoCommand();
for (int i = 0; i < 7; i++) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
}
public void setCommand(int slot, Command onCommand, Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = onCommand;
}
public void onButtonWasPushed(int slot) {
onCommands[slot].execute();
}
public void offButtonWasPushed(int slot) {
offCommands[slot].execute();
}
@Override
public String toString() {
return "RemoteControl{" +
"onCommands=" + Arrays.toString(onCommands) +
", offCommands=" + Arrays.toString(offCommands) +
'}';
}
}
버튼이 7개 있는 오토메이션 기기에 각 버튼마다 command를 지정해주고, 버튼이 눌리면 해당 버튼에 지정된 command의 execute를 실행하는 방식이다.
noCommand
노커맨드는 아무것도 실행하지 않는 커맨드이다.
모든 버튼에 커맨드가 매핑되어야하기에 이러한 커맨드를 사용해서 모든 버튼에 커맨드를 매핑할 수 있다.
클라이언트가 생성한 커맨드들을 전부 큐에 저장해놨다가 한참 후에 호출 하는 작업이 가능해진다.
이런 식으로 효율적으로 처리가 가능해진다.
클라이언트의 요청을 로그에 기록해놨다가 장애 발생시 그 로그를 복구해서 장애를 회복할 수 있다.