요청을 캡슐화하여 호출자(invoker)와 수신자(receiver)를 분리하는 패턴이다. 요청을 처리하는 방법이 바뀌더라도 호출자의 코드는 변경되지 않는다.
public class Light {
private boolean isOn;
public void on() {
System.out.println("불을 켭니다.");
this.isOn = true;
}
public void off() {
System.out.println("불을 끕니다.");
this.isOn = false;
}
public boolean isOn() {
return this.isOn;
}
}
public interface Command {
void execute();
void undo();
}
public class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
new LightOnCommand(this.light).execute();
}
}
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
new LightOffCommand(this.light).execute();
}
}
public class Button {
private Stack<Command> commands = new Stack<>();
public void press(Command command) {
command.execute();
commands.push(command);
}
public void undo() {
if(!commands.isEmpty()) {
Command command = Commands.pop();
command.undo();
}
}
public static void main(String[] args) {
Button button = new Button();
button.press(new LightOnCommand(new Light()));
button.undo();
}
}