设计模式-第六章-命令模式

194 阅读2分钟

设计模式-第六章-命令模式

代码

public interface Command {
    public void execute();
    public void undo();
}


public class Light {
    public Light(String name){
        System.out.println("I am  " + name + " light");
    }
    public void on(){
        System.out.println("the light turn on");
    }

    public void off(){
        System.out.println("the light turn off");
    }


}


public class LightOffCommand implements Command {
    Light light;

    public LightOffCommand(Light light){
        this.light = light;
        /* receiver */
    }
    @Override
    public void execute() {
        light.on();
    }

    public void undo(){
        light.off();
    }
}

public class LightOnCommand implements Command {
    Light light;

    public LightOnCommand(Light light){
        this.light = light;
        /* receiver */
    }
    @Override
    public void execute() {
        light.on();
    }

    public void undo(){
        light.off();
    }
}

public class SimpleRemoteControl {
    Command slot;
    public SimpleRemoteControl(){
    }

    public void SetCommand(Command command){
        this.slot = command;
    }

    public void buttownWasPressed(){
        slot.execute();
    }
}

public class RemoteControlTest {

    public static void main(String[] args) {
        SimpleRemoteControl remote = new SimpleRemoteControl();
        Light light = new Light("livining room");
        Command lightOn = new LightOnCommand(light);
        remote.SetCommand(lightOn);

        remote.buttownWasPressed();
    }
}

/*
Control -> Command -> Receiver

为什么不直接把light.on传入遥控器呢,大概是因为面向对象所以需要多封装一层command,除此之外我们命令还封装了一个undo功能

遥控器有slot关联command(has),又有动态更新command的方法setCommand
command关联receiver的action(has)

 */

个人注解

一般来说如果遥控器要控制light,把light对象传进去,然后在buttownWasPressed方法调用light.on()

但是由于需要undo(撤消),所以又封装了一层Command,分别有两个方法: execute、undo

但实际上无论是light的on,off还是undo都可以用状态模式来搞定(context)


代码

public class Nocommand implements Command {
    @Override
    public void execute() {

    }

    @Override
    public void undo() {

    }
}


public class RemoteControl {
    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;
    }

    public void setCommands(int slot,Command onCommand,Command offCommand){
        onCommands[slot] = onCommand;
        offCommands[slot] = offCommand;
    }

    public void onButtonWasPushed(int slot){
        if(onCommands != null) {
            onCommands[slot].execute();
        }
        undoCommand = onCommands[slot];
    }

    public void offButtonWasPushed(int slot){

        if(offCommands[slot] != null){
            offCommands[slot].execute();
        }
        undoCommand = offCommands[slot];
    }

    public void undoButtonWasPushed(){
        if(undoCommand != null){
            System.out.println("========== undo ============");
            undoCommand.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 RemoteLoader {
    public static void main(String[] args) {
        RemoteControl remoteControl = new RemoteControl();
        Light livingRoomLight = new Light("living room");
        LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight);
        LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight);
        remoteControl.setCommands(0,livingRoomLightOn,livingRoomLightOff);
        remoteControl.onButtonWasPushed(0);
        remoteControl.undoButtonWasPushed();
        remoteControl.offButtonWasPushed(0);
        System.out.println(remoteControl.toString());
    }
}