Object 구성부가 추가되면 abstract부분부터 수정해야 한다.
Client 소스
public class RemoteLoader {
public static void main(String[] args) {
RemoteControl remoteControl = new RemoteControl();
CeilingFan ceilingFan = new CeilingFan("Living Room");
CeilingFanHighCommand ceilingFanHigh = new CeilingFanHighCommand(ceilingFan);
CeilingFanOffCommand ceilingFanOff = new CeilingFanOffCommand(ceilingFan);
remoteControl.setCommand(2, ceilingFanHigh, ceilingFanOff);
System.out.println(remoteControl);
remoteControl.onButtonWasPushed(0);
remoteControl.offButtonWasPushed(0);
remoteControl.undoButtonWasPushed();
remoteControl.onButtonWasPushed(2);
remoteControl.offButtonWasPushed(2);
remoteControl.undoButtonWasPushed();
}
}
/**
* Receiver (천장의 FAN을 작동시킨다)
*/
public 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) {
// TODO Auto-generated constructor stub
this.location=location;
speed=OFF;
}
public void high(){
speed = HIGH;
}
public void medium(){
speed = MEDIUM;
}
public void low(){
speed = LOW;
}
public void off(){
speed = OFF;
}
public int getSpeed(){
return speed;
}
}
/**
* Invoker
*/
public class RemoteControl {
Command[] onCommands;
Command[] offCommands;
Command undoCommand;
public RemoteControl() {
// TODO Auto-generated constructor stub
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;
}
/**
* @param slot
* @param onCommand
* @param offCommand
* 리모컨의 각 slot에 command를 넣는다.
*/
public void setCommand(int slot, Command onCommand, Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}
/**
* @param slot
* slot의 ON button이 눌리면 그 slot의 OnCommand의 execute()메소드가 호출된다.
*/
public void onButtonWasPushed(int slot) {
onCommands[slot].execute();
undoCommand = onCommands[slot];
}
public void offButtonWasPushed(int slot) {
offCommands[slot].execute();
undoCommand = offCommands[slot];
}
@Override
public String toString() {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("\n-----Remote Control-----\n");
for(int i=0; i<onCommands.length; i++){
stringBuffer.append("[slot " + i + "] " + onCommands[i].getClass().getName()+"\n");
}
return stringBuffer.toString();
}
public void undoButtonWasPushed() {
// TODO Auto-generated method stub
undoCommand.undo();
}
}
/**
* 이 class는 fan 속도를 높이고, Receiver인 CeilingFan 사이를 bind한다.
*/
public class CeilingFanHighCommand implements Command{
CeilingFan ceilingFan;
int prevSpeed;
public CeilingFanHighCommand(CeilingFan ceilingFan) {
// TODO Auto-generated constructor stub
this.ceilingFan=ceilingFan;
}
/*
* Invoker에서 execute를 호출하면 fan 속도를 높인다.
* unDo를 구현하기 위해 prevSpeed에 속도 값을 저장해 둔다.
*/
@Override
public void execute() {
// TODO Auto-generated method stub
prevSpeed = ceilingFan.getSpeed();
ceilingFan.high();
}
/*
* prevSpeed를 기준으로 speed를 설정한다.
*/
@Override
public void undo() {
// TODO Auto-generated method stub
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();
}
}
}
public class CeilingFanOffCommand implements Command{
CeilingFan ceilingFan;
int prevSpeed;
public CeilingFanOffCommand(CeilingFan ceilingFan) {
// TODO Auto-generated constructor stub
this.ceilingFan = ceilingFan;
}
@Override
public void execute() {
// TODO Auto-generated method stub
prevSpeed = ceilingFan.getSpeed();
ceilingFan.off();
}
@Override
public void undo() {
// TODO Auto-generated method stub
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();
}
}
}
/**
* 이 class는 null object이다.
* return할 object는 없어도 client에서 null을 처리하지 않아도
* 되게 할 때 사용한다.
*/
public class NoCommand implements Command{
@Override
public void execute() {
// TODO Auto-generated method stub
}
@Override
public void undo() {
// TODO Auto-generated method stub
}
}
/**
* 모든 command에서 구현해야 하는 interface이다.
* 모든 command는 execute method를 통해서 호출되며,
* 이 method에서는 receiver에 특정 작업을 처리하게 한다.
*/
public interface Command {
public void execute();
public void undo();
}