요청 내역을 객체로 캡슐화해서 객체를 서로 다른 요청 내역에 따라 매개변수화할 수 있다. 요청을 큐에 저장하거나 로그로 기록하거나 작업 취소 기능, 트랜잭션 시스템을 구현할 수 있다.
리모컨의 각 슬롯을 클릭했을 때, 명령을 통해 행동을 수행하고 각 슬롯마다 다른 명령을 수행해야 한다.
Command Interface
public interface Command {
public void execute();
}
Command Concrete
public class LightOnCommand implements Command{
Light light;
// 특정 조명 객체를 받아 인스턴스 변수에 저장
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.on(); // light 객체를 리시버로 지정
}
}
public class LightOffCommand implements Command{
Light light;
// 특정 조명 객체를 받아 인스턴스 변수에 저장
public LightOffCommand(Light light) {
this.light = light;
}
public void execute() {
light.off(); // light 객체를 리시버로 지정
}
}
Receiver Class
public 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");
}
}
Invoker Class
public class RemoteControl {
// on, off 명령어를 저장할 배열
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;
}
}
// 명령어 저장 메서드 - slot 번호에 on,off 커맨드 객체 저장
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();
}
public String toString() {
StringBuffer stringBuff = new StringBuffer();
stringBuff.append("\n------ Remote Control -------\n");
for (int i = 0; i < onCommands.length; i++) {
stringBuff.append("[slot " + i + "] " + onCommands[i].getClass().getName()
+ " " + offCommands[i].getClass().getName() + "\n");
}
return stringBuff.toString();
}
}
Test.java
public class RemoteControlTest{
public static void main(String[] args) {
RemoteControl remote = new RemoteControl(); // 인보커 객체 생성
Light livingRoomlight = new Light("Living Room"); // 위치에 맞게 객체 생성 - 리시버 객체 생성
// 커맨드 객체 생성
LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight);
LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight);
remote.setCommand(0, livingRoomLightOn, livingRoomLightOff); // 커맨드 객체를 인보커에게 전달, 행위를 슬롯에 저장
// remote.setCommand(0, ()->livingRoomLight.on(), ()->livingRoomLight.off());
remote.onButtonWasPressed(0); // 리시버에 있는 행동 메서드 수행
remote.offButtonWasPressed(0);
}
}
Command Class
public interface Command{
public void execute();
public void undo();
}
public class LightOnCommand implements Command {
Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.on;
}
public void undo() {
light.off; // light on 이전 상태이므로 off
}
}
Receiver Class
Invoker Class
public class RemoteControl {
// on, off 명령어를 저장할 배열
Command[] onCommands;
Command[] offCommands;
Command undoCommand;
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;
}
undoCommand = noCommand;
}
// 명령어 저장 메서드 - slot 번호에 on,off 커맨드 객체 저장
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]; // 해당 객체를 undoCommand 레퍼런스 변수로 저장
}
public void offButtonWasPushed(int slot) {
offCommands[slot].execute();
undoCommand = offCommands[slot];// 해당 객체를 undoCommand 레퍼런스 변수로 저장
}
//undo 버튼 클릭할 시
public void undoButtonWasPushed(int slot) {
undoCommand.undo(); // undo 메서드 호출
}
public String toString() {
StringBuffer stringBuff = new StringBuffer();
stringBuff.append("\n------ Remote Control -------\n");
for (int i = 0; i < onCommands.length; i++) {
stringBuff.append("[slot " + i + "] " + onCommands[i].getClass().getName()
+ " " + offCommands[i].getClass().getName() + "\n");
}
return stringBuff.toString();
}
}
public class MacroCommand implements Command {
Command[] commands;
// 커맨드들을 받아 저장
public MacroCommand(Command[] commands) {
this.commands = commands;
}
// 커맨드들을 순서대로 처리
public void execute() {
for(int i = 0; i<commands.length; i++) {
commands[i].execute();
}
}
}