메소드 호출을 캡슐화
커맨드 패턴은 작업을 요청하는 쪽과 작업을 처리하는 쪽을 분리할 수 있다.
커맨드 객체는 특정 객체에 관한 특정 작업 요청을 캡슐화한다.
커맨드 패턴 소개
구성요소 클라이언트, 인보커, 커맨드, 리시버
클라이언트는 커맨드 객체를 생성한다.
커맨드 객체 안에는 리시버가 있다.
리시버는 실제로 동작을 수행하는 역할을 한다.
커맨드 객체는 인보커에 저장된다.
인보커는 클라이언트 요청으로 저장된 커맨드 객체를 실행한다.
커맨드 객체에 동작은 리시버가 한다.
public class CommandTest {
//리시버
static class Light {
public Light() { }
public void on() {
System.out.println("Light is on");
}
public void off() {
System.out.println("Light is off");
}
}
static class GarageDoor {
public GarageDoor() {
}
public void up() {
System.out.println("Garage Door is Open");
}
public void down() {
System.out.println("Garage Door is Closed");
}
public void stop() {
System.out.println("Garage Door is Stopped");
}
public void lightOn() {
System.out.println("Garage light is on");
}
public void lightOff() {
System.out.println("Garage light is off");
}
}
//커맨드
@FunctionalInterface
static interface Command{
void execute();
}
static class LightOnCommand implements Command{
Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.on();
}
}
static class GarageDoorOpenCommand implements Command{
GarageDoor garageDoor;
public GarageDoorOpenCommand(GarageDoor garageDoor) {
this.garageDoor = garageDoor;
}
@Override
public void execute() {
garageDoor.up();
}
}
//인보커
static class SimpleRemoteControl{
Command slot;
public SimpleRemoteControl() { }
public void setCommand(Command slot) {
this.slot = slot;
}
public void buttonWasPressed() {
slot.execute();
}
}
//클라이언트(편의상 main이 이 역할), 커맨드 객체 생성, 인보커에게 커맨드 객체 전달
public static void main(String[] args) {
//인보커, 내부에 커맨드 객체를 저장하고, 다시 요청이 오면 커맨드 객체를 실행
SimpleRemoteControl remoteControl = new SimpleRemoteControl();
//리시버, 실제 동작을 수행하는 객체
Light light = new Light();
//커맨드, 외부와 내부에 리시버에게 동작을 위임한다.
LightOnCommand lightOnCommand = new LightOnCommand(light);
//인보커에 커맨드 저장
remoteControl.setCommand(lightOnCommand);
//클라이언트가 저장한 커맨드 객체 실행 요청, 이 메서드는 단순히 리시버에 동작을 위임한다.
remoteControl.buttonWasPressed();
GarageDoor garageDoor = new GarageDoor();
GarageDoorOpenCommand garageDoorOpenCommand = new GarageDoorOpenCommand(garageDoor);
remoteControl.setCommand(garageDoorOpenCommand);
remoteControl.buttonWasPressed();
}
}
Light is on
Garage Door is Open
커맨드 패턴의 정의
요청 내역을 객체로 캡슐화해서 객체를 서로 다른 요청 내역에 따라 매개변수화할 수 있다.
요청을 따로 큐 같은 자료구조에 저장해 실행 전에 작업 취소 같은 기능 구현도 가능하다.
import java.util.*;
public class 심플커맨드 {
static interface Command{
void execute();
}
static class Invoker{
//큐 예시
private final Queue<Command> commands = new LinkedList<>();
public void addCommand(Command command) {
this.commands.add(command);
}
public void action() {
if(!commands.isEmpty())
commands.poll().execute();
else System.out.println("더 이상의 요청은 없어요!");
}
}
public static void main(String[] args) {
Invoker invoker = new Invoker();
invoker.addCommand(()->System.out.println("커맨드 객체는 요청을 캡슐화합니다."));
invoker.addCommand(()->System.out.println("커맨드 객체는 요청을 캡슐화합니다."));
invoker.action();
invoker.action();
invoker.action();
}
}
커맨드 객체는 요청을 캡슐화합니다.
커맨드 객체는 요청을 캡슐화합니다.
더 이상의 요청은 없어요!
켜고 끄는 슬롯이 존재하는 커맨드 패턴 구현
public class CommandTest2 { // 리시버 static class Light { String location = ""; public Light(String location) { this.location = location; } public void on() { System.out.println(location + " light is on"); } public void off() { System.out.println(location + " light is off"); } } static class TV { String location; int channel; public TV(String location) { this.location = location; } public void on() { System.out.println("TV is on"); } public void off() { System.out.println("TV is off"); } public void setInputChannel() { this.channel = 3; System.out.println("Channel is set for VCR"); } } static class Stereo { String location; public Stereo(String location) { this.location = location; } public void on() { System.out.println(location + " stereo is on"); } public void off() { System.out.println(location + " stereo is off"); } public void setCD() { System.out.println(location + " stereo is set for CD input"); } public void setDVD() { System.out.println(location + " stereo is set for DVD input"); } public void setRadio() { System.out.println(location + " stereo is set for Radio"); } public void setVolume(int volume) { // code to set the volume // valid range: 1-11 (after all 11 is better than 10, right?) System.out.println(location + " stereo volume set to " + volume); } } static class Hottub { boolean on; int temperature; public Hottub() { } public void on() { on = true; } public void off() { on = false; } public void bubblesOn() { if (on) { System.out.println("Hottub is bubbling!"); } } public void bubblesOff() { if (on) { System.out.println("Hottub is not bubbling"); } } public void jetsOn() { if (on) { System.out.println("Hottub jets are on"); } } public void jetsOff() { if (on) { System.out.println("Hottub jets are off"); } } public void setTemperature(int temperature) { this.temperature = temperature; } public void heat() { temperature = 105; System.out.println("Hottub is heating to a steaming 105 degrees"); } public void cool() { temperature = 98; System.out.println("Hottub is cooling to 98 degrees"); } } static class CeilingFan { String location = ""; int level; public static final int HIGH = 2; public static final int MEDIUM = 1; public static final int LOW = 0; public CeilingFan(String location) { this.location = location; } public void high() { // turns the ceiling fan on to high level = HIGH; System.out.println(location + " ceiling fan is on high"); } public void medium() { // turns the ceiling fan on to medium level = MEDIUM; System.out.println(location + " ceiling fan is on medium"); } public void low() { // turns the ceiling fan on to low level = LOW; System.out.println(location + " ceiling fan is on low"); } public void off() { // turns the ceiling fan off level = 0; System.out.println(location + " ceiling fan is off"); } public int getSpeed() { return level; } } static class GarageDoor { String location; public GarageDoor(String location) { this.location = location; } public void up() { System.out.println(location + " garage Door is Up"); } public void down() { System.out.println(location + " garage Door is Down"); } public void stop() { System.out.println(location + " garage Door is Stopped"); } public void lightOn() { System.out.println(location + " garage light is on"); } public void lightOff() { System.out.println(location + " garage light is off"); } } // 커맨드 @FunctionalInterface static interface Command { void execute(); } static class NoCommand implements Command { public void execute() { } } static class LightOnCommand implements Command { Light light; public LightOnCommand(Light light) { this.light = light; } public void execute() { light.on(); } } static class LightOffCommand implements Command { Light light; public LightOffCommand(Light light) { this.light = light; } public void execute() { light.off(); } } static class GarageDoorUpCommand implements Command { GarageDoor garageDoor; public GarageDoorUpCommand(GarageDoor garageDoor) { this.garageDoor = garageDoor; } public void execute() { garageDoor.up(); } } static class GarageDoorDownCommand implements Command { GarageDoor garageDoor; public GarageDoorDownCommand(GarageDoor garageDoor) { this.garageDoor = garageDoor; } public void execute() { garageDoor.up(); } } static class StereoOnWithCDCommand implements Command { Stereo stereo; public StereoOnWithCDCommand(Stereo stereo) { this.stereo = stereo; } public void execute() { stereo.on(); stereo.setCD(); stereo.setVolume(11); } } static class StereoOffCommand implements Command { Stereo stereo; public StereoOffCommand(Stereo stereo) { this.stereo = stereo; } public void execute() { stereo.off(); } } static class CeilingFanOnCommand implements Command { CeilingFan ceilingFan; public CeilingFanOnCommand(CeilingFan ceilingFan) { this.ceilingFan = ceilingFan; } public void execute() { ceilingFan.high(); } } static class CeilingFanOffCommand implements Command { CeilingFan ceilingFan; public CeilingFanOffCommand(CeilingFan ceilingFan) { this.ceilingFan = ceilingFan; } public void execute() { ceilingFan.off(); } } static class LivingroomLightOnCommand implements Command { Light light; public LivingroomLightOnCommand(Light light) { this.light = light; } public void execute() { light.on(); } } static class LivingroomLightOffCommand implements Command { Light light; public LivingroomLightOffCommand(Light light) { this.light = light; } public void execute() { light.off(); } } static class HottubOnCommand implements Command { Hottub hottub; public HottubOnCommand(Hottub hottub) { this.hottub = hottub; } public void execute() { hottub.on(); hottub.heat(); hottub.bubblesOn(); } } static class HottubOffCommand implements Command { Hottub hottub; public HottubOffCommand(Hottub hottub) { this.hottub = hottub; } public void execute() { hottub.cool(); hottub.off(); } } // 인보커 static 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 < offCommands.length; i++) { onCommands[i] = noCommand; offCommands[i] = noCommand; } } public void setCommand(int slot, Command onCommand, Command offCommand) { onCommands[slot] = onCommand; offCommands[slot] = offCommand; } public void onButtonWasPushed(int slot) { onCommands[slot].execute(); } public void offButtonWasPushed(int slot) { offCommands[slot].execute(); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("\n------ 리모컨 ------\n"); for (int i = 0; i < offCommands.length; i++) { sb.append("[slot" + i + "]" + onCommands[i].getClass().getSimpleName()); sb.append(" " + offCommands[i].getClass().getSimpleName()+"\n"); } return sb.toString(); } } // 클라이언트, 커맨드 객체 생성, 인보커에게 커맨드 객체 전달 public static void main(String[] args) { RemoteControl remoteControl = new RemoteControl(); Light livingRoomLight = new Light("Living Room"); Light kitchenLight = new Light("Kitchen"); CeilingFan ceilingFan= new CeilingFan("Living Room"); GarageDoor garageDoor = new GarageDoor("Garage"); Stereo stereo = new Stereo("Living Room"); LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight); LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight); LightOnCommand kitchenLightOn = new LightOnCommand(kitchenLight); LightOffCommand kitchenLightOff = new LightOffCommand(kitchenLight); CeilingFanOnCommand ceilingFanOn = new CeilingFanOnCommand(ceilingFan); CeilingFanOffCommand ceilingFanOff = new CeilingFanOffCommand(ceilingFan); GarageDoorUpCommand garageDoorUp = new GarageDoorUpCommand(garageDoor); GarageDoorDownCommand garageDoorDown = new GarageDoorDownCommand(garageDoor); StereoOnWithCDCommand stereoOnWithCD = new StereoOnWithCDCommand(stereo); StereoOffCommand stereoOff = new StereoOffCommand(stereo); remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff); remoteControl.setCommand(1, kitchenLightOn, kitchenLightOff); remoteControl.setCommand(2, ceilingFanOn, ceilingFanOff); remoteControl.setCommand(3, stereoOnWithCD, stereoOff); System.out.println(remoteControl); remoteControl.onButtonWasPushed(0); remoteControl.offButtonWasPushed(0); remoteControl.onButtonWasPushed(1); remoteControl.offButtonWasPushed(1); remoteControl.onButtonWasPushed(2); remoteControl.offButtonWasPushed(2); remoteControl.onButtonWasPushed(3); remoteControl.offButtonWasPushed(3); } } |
------ 리모컨 ------ [slot0]LightOnCommand LightOffCommand [slot1]LightOnCommand LightOffCommand [slot2]CeilingFanOnCommand CeilingFanOffCommand [slot3]StereoOnWithCDCommand StereoOffCommand [slot4]NoCommand NoCommand [slot5]NoCommand NoCommand [slot6]NoCommand NoCommand Living Room light is on Living Room light is off Kitchen light is on Kitchen light is off Living Room ceiling fan is on high Living Room ceiling fan is off Living Room stereo is on Living Room stereo is set for CD input Living Room stereo volume set to 11 Living Room stereo is off |
즐겨찾기 처럼 슬롯에 저장해둔 커맨드 객체는 언제든지 호출할 수 있다.
4~6 슬롯에 NoCommand 객체는 아무런 일도 안한다. 일종의 Null 객체로 이렇게 구현해두면 호출하는 쪽에서 Null 걱정을 을 할필요가 없다.
실행 했던 커맨드 되돌리기
public class CommandTest3 { // 리시버 static class Light { String location = ""; public Light(String location) { this.location = location; } public void on() { System.out.println(location + " light is on"); } public void off() { System.out.println(location + " light is off"); } } static class TV { String location; int channel; public TV(String location) { this.location = location; } public void on() { System.out.println("TV is on"); } public void off() { System.out.println("TV is off"); } public void setInputChannel() { this.channel = 3; System.out.println("Channel is set for VCR"); } } static class Stereo { String location; public Stereo(String location) { this.location = location; } public void on() { System.out.println(location + " stereo is on"); } public void off() { System.out.println(location + " stereo is off"); } public void setCD() { System.out.println(location + " stereo is set for CD input"); } public void setDVD() { System.out.println(location + " stereo is set for DVD input"); } public void setRadio() { System.out.println(location + " stereo is set for Radio"); } public void setVolume(int volume) { // code to set the volume // valid range: 1-11 (after all 11 is better than 10, right?) System.out.println(location + " stereo volume set to " + volume); } } static class Hottub { boolean on; int temperature; public Hottub() { } public void on() { on = true; } public void off() { on = false; } public void bubblesOn() { if (on) { System.out.println("Hottub is bubbling!"); } } public void bubblesOff() { if (on) { System.out.println("Hottub is not bubbling"); } } public void jetsOn() { if (on) { System.out.println("Hottub jets are on"); } } public void jetsOff() { if (on) { System.out.println("Hottub jets are off"); } } public void setTemperature(int temperature) { this.temperature = temperature; } public void heat() { temperature = 105; System.out.println("Hottub is heating to a steaming 105 degrees"); } public void cool() { temperature = 98; System.out.println("Hottub is cooling to 98 degrees"); } } static class CeilingFan { public static final int HIGH = 3; public static final int MEDIUM = 2; public static final int LOW = 1; public static final int OFF = 0; String location; int speed; public CeilingFan(String location) { this.location = location; speed = OFF; } public void high() { speed = HIGH; System.out.println(location + " ceiling fan is on high"); } public void medium() { speed = MEDIUM; System.out.println(location + " ceiling fan is on medium"); } public void low() { speed = LOW; System.out.println(location + " ceiling fan is on low"); } public void off() { speed = OFF; System.out.println(location + " ceiling fan is off"); } public int getSpeed() { return speed; } } static class GarageDoor { String location; public GarageDoor(String location) { this.location = location; } public void up() { System.out.println(location + " garage Door is Up"); } public void down() { System.out.println(location + " garage Door is Down"); } public void stop() { System.out.println(location + " garage Door is Stopped"); } public void lightOn() { System.out.println(location + " garage light is on"); } public void lightOff() { System.out.println(location + " garage light is off"); } } // 커맨드 static interface Command { void execute(); void undo(); } static class NoCommand implements Command { public void execute() { } public void undo() { } } static class LightOnCommand implements Command { Light light; public LightOnCommand(Light light) { this.light = light; } public void execute() { light.on(); } public void undo() { light.off(); } } static class LightOffCommand implements Command { Light light; public LightOffCommand(Light light) { this.light = light; } public void execute() { light.off(); } @Override public void undo() { light.on(); } } static class GarageDoorUpCommand implements Command { GarageDoor garageDoor; public GarageDoorUpCommand(GarageDoor garageDoor) { this.garageDoor = garageDoor; } public void execute() { garageDoor.up(); } @Override public void undo() { garageDoor.down(); } } static class GarageDoorDownCommand implements Command { GarageDoor garageDoor; public GarageDoorDownCommand(GarageDoor garageDoor) { this.garageDoor = garageDoor; } public void execute() { garageDoor.down(); } public void undo() { garageDoor.up(); } } static class StereoOnWithCDCommand implements Command { Stereo stereo; public StereoOnWithCDCommand(Stereo stereo) { this.stereo = stereo; } public void execute() { stereo.on(); stereo.setCD(); stereo.setVolume(11); } @Override public void undo() { stereo.off(); } } static class StereoOffCommand implements Command { Stereo stereo; int prev; public StereoOffCommand(Stereo stereo) { this.stereo = stereo; } public void execute() { stereo.off(); } @Override public void undo() { stereo.on(); stereo.setCD(); stereo.setVolume(11); } } static class CeilingFanHighCommand implements Command { CeilingFan ceilingFan; int prevSpeed; public CeilingFanHighCommand(CeilingFan ceilingFan) { this.ceilingFan = ceilingFan; } public void execute() { prevSpeed = ceilingFan.getSpeed(); ceilingFan.high(); } public void undo() { if (prevSpeed == CeilingFan.HIGH) { ceilingFan.high(); } else if (prevSpeed == CeilingFan.MEDIUM) { ceilingFan.medium(); } else if (prevSpeed == CeilingFan.LOW) { ceilingFan.low(); } else if (prevSpeed == CeilingFan.OFF) { ceilingFan.off(); } } } static class CeilingFanMediumCommand implements Command { CeilingFan ceilingFan; int prevSpeed; public CeilingFanMediumCommand(CeilingFan ceilingFan) { this.ceilingFan = ceilingFan; } public void execute() { prevSpeed = ceilingFan.getSpeed(); ceilingFan.medium(); } public void undo() { if (prevSpeed == CeilingFan.HIGH) { ceilingFan.high(); } else if (prevSpeed == CeilingFan.MEDIUM) { ceilingFan.medium(); } else if (prevSpeed == CeilingFan.LOW) { ceilingFan.low(); } else if (prevSpeed == CeilingFan.OFF) { ceilingFan.off(); } } } static class CeilingFanLowCommand implements Command { CeilingFan ceilingFan; int prevSpeed; public CeilingFanLowCommand(CeilingFan ceilingFan) { this.ceilingFan = ceilingFan; } public void execute() { prevSpeed = ceilingFan.getSpeed(); ceilingFan.low(); } public void undo() { if (prevSpeed == CeilingFan.HIGH) { ceilingFan.high(); } else if (prevSpeed == CeilingFan.MEDIUM) { ceilingFan.medium(); } else if (prevSpeed == CeilingFan.LOW) { ceilingFan.low(); } else if (prevSpeed == CeilingFan.OFF) { ceilingFan.off(); } } } static class CeilingFanOffCommand implements Command { CeilingFan ceilingFan; int prevSpeed; public CeilingFanOffCommand(CeilingFan ceilingFan) { this.ceilingFan = ceilingFan; } public void execute() { prevSpeed = ceilingFan.getSpeed(); ceilingFan.off(); } public void undo() { if (prevSpeed == CeilingFan.HIGH) { ceilingFan.high(); } else if (prevSpeed == CeilingFan.MEDIUM) { ceilingFan.medium(); } else if (prevSpeed == CeilingFan.LOW) { ceilingFan.low(); } else if (prevSpeed == CeilingFan.OFF) { ceilingFan.off(); } } } static class LivingroomLightOnCommand implements Command { Light light; public LivingroomLightOnCommand(Light light) { this.light = light; } public void execute() { light.on(); } public void undo() { light.off(); } } static class LivingroomLightOffCommand implements Command { Light light; public LivingroomLightOffCommand(Light light) { this.light = light; } public void execute() { light.off(); } public void undo() { light.on(); } } static class HottubOnCommand implements Command { Hottub hottub; public HottubOnCommand(Hottub hottub) { this.hottub = hottub; } public void execute() { hottub.on(); hottub.heat(); hottub.bubblesOn(); } public void undo() { hottub.cool(); hottub.off(); } } static class HottubOffCommand implements Command { Hottub hottub; public HottubOffCommand(Hottub hottub) { this.hottub = hottub; } public void execute() { hottub.cool(); hottub.off(); } @Override public void undo() { hottub.on(); hottub.heat(); hottub.bubblesOn(); } } // 인보커 static class RemoteControlWithUndo { Command[] onCommands; Command[] offCommands; Command undoCommand; public RemoteControlWithUndo() { onCommands = new Command[7]; offCommands = new Command[7]; Command noCommand = new NoCommand(); for (int i = 0; i < offCommands.length; i++) { onCommands[i] = noCommand; offCommands[i] = noCommand; } undoCommand = noCommand; } public void setCommand(int slot, Command onCommand, Command offCommand) { onCommands[slot] = onCommand; offCommands[slot] = offCommand; } public void onButtonWasPushed(int slot) { onCommands[slot].execute(); undoCommand = onCommands[slot]; } public void offButtonWasPushed(int slot) { offCommands[slot].execute(); undoCommand = offCommands[slot]; } public void undoButtonWasPushed() { undoCommand.undo(); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("\n------ 리모컨 ------\n"); for (int i = 0; i < offCommands.length; i++) { sb.append("[slot" + i + "]" + onCommands[i].getClass().getSimpleName()); sb.append(" " + offCommands[i].getClass().getSimpleName() + "\n"); } sb.append("[undo] " + undoCommand.getClass().getSimpleName() + "\n"); return sb.toString(); } } // 클라이언트, 커맨드 객체 생성, 인보커에게 커맨드 객체 전달 public static void main(String[] args) { RemoteControlWithUndo remoteControl = new RemoteControlWithUndo(); Light livingRoomLight = new Light("Living Room"); LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight); LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight); remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff); remoteControl.onButtonWasPushed(0); remoteControl.offButtonWasPushed(0); System.out.println(remoteControl); remoteControl.undoButtonWasPushed(); remoteControl.offButtonWasPushed(0); remoteControl.onButtonWasPushed(0); System.out.println(remoteControl); remoteControl.undoButtonWasPushed(); CeilingFan ceilingFan = new CeilingFan("Living Room"); CeilingFanMediumCommand ceilingFanMedium = new CeilingFanMediumCommand(ceilingFan); CeilingFanHighCommand ceilingFanHigh = new CeilingFanHighCommand(ceilingFan); CeilingFanOffCommand ceilingFanOff = new CeilingFanOffCommand(ceilingFan); remoteControl.setCommand(0, ceilingFanMedium, ceilingFanOff); remoteControl.setCommand(1, ceilingFanHigh, ceilingFanOff); remoteControl.onButtonWasPushed(0); remoteControl.offButtonWasPushed(0); System.out.println(remoteControl); remoteControl.undoButtonWasPushed(); remoteControl.onButtonWasPushed(1); System.out.println(remoteControl); remoteControl.undoButtonWasPushed(); } } |
Living Room light is on Living Room light is off ------ 리모컨 ------ [slot0]LightOnCommand LightOffCommand [slot1]NoCommand NoCommand [slot2]NoCommand NoCommand [slot3]NoCommand NoCommand [slot4]NoCommand NoCommand [slot5]NoCommand NoCommand [slot6]NoCommand NoCommand [undo] LightOffCommand Living Room light is on Living Room light is off Living Room light is on ------ 리모컨 ------ [slot0]LightOnCommand LightOffCommand [slot1]NoCommand NoCommand [slot2]NoCommand NoCommand [slot3]NoCommand NoCommand [slot4]NoCommand NoCommand [slot5]NoCommand NoCommand [slot6]NoCommand NoCommand [undo] LightOnCommand Living Room light is off Living Room ceiling fan is on medium Living Room ceiling fan is off ------ 리모컨 ------ [slot0]CeilingFanMediumCommand CeilingFanOffCommand [slot1]CeilingFanHighCommand CeilingFanOffCommand [slot2]NoCommand NoCommand [slot3]NoCommand NoCommand [slot4]NoCommand NoCommand [slot5]NoCommand NoCommand [slot6]NoCommand NoCommand [undo] CeilingFanOffCommand Living Room ceiling fan is on medium Living Room ceiling fan is on high ------ 리모컨 ------ [slot0]CeilingFanMediumCommand CeilingFanOffCommand [slot1]CeilingFanHighCommand CeilingFanOffCommand [slot2]NoCommand NoCommand [slot3]NoCommand NoCommand [slot4]NoCommand NoCommand [slot5]NoCommand NoCommand [slot6]NoCommand NoCommand [undo] CeilingFanHighCommand Living Room ceiling fan is on medium |
여러개 커맨드 한번에 실행
static class MacroCommand implements Command{ Command[] commands; public MacroCommand(Command[] commands) { this.commands = commands; } public void execute() { for(Command command : commands) { command.execute(); } } public void undo() { for(Command command : commands) { command.undo(); } } } public static void main(String[] args) { RemoteControl remoteControl = new RemoteControl(); Light light = new Light("Living Room"); TV tv = new TV("Living Room"); Stereo stereo = new Stereo("Living Room"); Hottub hottub = new Hottub(); LightOnCommand lightOn = new LightOnCommand(light); StereoOnCommand stereoOn = new StereoOnCommand(stereo); TVOnCommand tvOn = new TVOnCommand(tv); HottubOnCommand hottubOn = new HottubOnCommand(hottub); LightOffCommand lightOff = new LightOffCommand(light); StereoOffCommand stereoOff = new StereoOffCommand(stereo); TVOffCommand tvOff = new TVOffCommand(tv); HottubOffCommand hottubOff = new HottubOffCommand(hottub); Command[] partyOn = { lightOn, stereoOn, tvOn, hottubOn}; Command[] partyOff = { lightOff, stereoOff, tvOff, hottubOff}; MacroCommand partyOnMacro = new MacroCommand(partyOn); MacroCommand partyOffMacro = new MacroCommand(partyOff); remoteControl.setCommand(0, partyOnMacro, partyOffMacro); System.out.println(remoteControl); System.out.println("--- Pushing Macro On---"); remoteControl.onButtonWasPushed(0); System.out.println("--- Pushing Macro Off---"); remoteControl.offButtonWasPushed(0); } |
------ 리모컨 ------ [slot0]MacroCommand MacroCommand [slot1]NoCommand NoCommand [slot2]NoCommand NoCommand [slot3]NoCommand NoCommand [slot4]NoCommand NoCommand [slot5]NoCommand NoCommand [slot6]NoCommand NoCommand [undo] NoCommand --- Pushing Macro On--- Living Room light is on Living Room stereo is on TV is on Channel is set for VCR Hottub is heating to a steaming 105 degrees Hottub is bubbling! --- Pushing Macro Off--- Living Room light is off Living Room stereo is off TV is off Hottub is cooling to 98 degrees |
커맨드 객체 배열을 한 번더 커맨드 객체로 캡슐화하여한 번에 요청으로 일련의 행동을 수행 할 수 있다.
핵심요약
커맨드 패턴을 사용하면 요청하는 객체와 요청을 수행하는 객체를 분리할 수 있다.
핵심은 커맨드 객체이며, 커맨드 객체는 실제 행동을 수행하는 리시버를 캡슐화한다.
'IT책, 강의 > 헤드 퍼스트 디자인 패턴' 카테고리의 다른 글
CHAPTER 08 알고리즘 캡슐화하기 템플릿 메소드 패턴 (0) | 2023.05.28 |
---|---|
CHAPTER 07 적응시키기 어댑터 패턴과 퍼사드 패턴 (0) | 2023.05.26 |
CHAPTER 05 하나뿐인 특별한 객체 만들기 (싱글턴 패턴) (0) | 2023.05.21 |
CHAPTER 04 객체지향 빵 굽기 팩토리 패턴 (0) | 2023.05.19 |
CHAPTER 03 객체 꾸미기 데코레이터 패턴 (1) | 2023.05.17 |