(命令模式)

命令模式

将方法调用封装起来,通过封装方法调用,将运算块包装成型。调用次运算的对象不需要关心事情是如何进行的,只要知道如何使用包装成型的方法来完成它就可以。应用于记录日志,或者重复使用这些封装来实现撤销。

命令模式可将“动作的请求者”从“动作的执行者”对象中解耦。

定义

==命令模式==将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。

1703510563146.png

  • receiver 接受者角色
  • command 命令角色
  • invoker 调用者角色

代码实现

  1. Receiver

    public class Light {
        String roomName;
        public Light(String room) {
            this.roomName = room;
        }
        public void on() {
            System.out.println(roomName + " light on...");
        }
    
        public void off() {
            System.out.println(roomName + " light off...");
        }
    
        public void noCommand() {
            System.out.println("no Command...");
        }
    }
    
  2. Command

    public interface Command {
        public void execute();
        public void undo();
    }
    
    /**
     *开灯
     */
    public class LightOnCommond implements Command {
        Light light;
        public LightOnCommond(Light light) {
            this.light = light;
        }
        @Override
        public void execute() {
            light.on();
        }
    
        @Override
        public void undo() {
            light.off();
        }
    }
    
    /**
     *关灯
     */
    public class LightOffCommond implements Command {
        Light light;
        public LightOffCommond(Light light) {
            this.light = light;
        }
        @Override
        public void execute() {
            light.off();
        }
    
        @Override
        public void undo() {
            light.on();
        }
    }
    
  3. Invoker

    public class RemoteController {
        Command[] onCommands;
        Command[] offCommands;
        Command undoCommand;
    
        public RemoteController() {
            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 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();
        }
    
        public String toString() {
            StringBuffer stringBuff = new StringBuffer();
            stringBuff.append("\n------ Remote Controller ------\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();
        }
    }
    
  4. 测试代码

    public class RemoteLoader {
        public static void main(String[] args) {
            RemoteController remoteController = new RemoteController();
            Light livingRoomLight =  new Light("Living Room");
            Light kitchenLight =  new Light("Kitchen");
    
            LightOnCommond livingRoomLightOn = new LightOnCommond(livingRoomLight);
            LightOffCommond livingRoomLightOff = new LightOffCommond(livingRoomLight);
            LightOnCommond kitchenLightOn = new LightOnCommond(kitchenLight);
            LightOffCommond kitchenLightOff = new LightOffCommond(kitchenLight);
    
            remoteController.setCommand(0, livingRoomLightOn, livingRoomLightOff);
            remoteController.setCommand(1, kitchenLightOn, kitchenLightOff);
    
            System.out.println(remoteController);
    
            remoteController.onButtonWasPushed(0);
            remoteController.offButtonWasPushed(0);
            remoteController.onButtonWasPushed(1);
            remoteController.offButtonWasPushed(1);
        }
    }
    
  5. 输出结果

    ------ Remote Controller ------
    [slot 0] com.cjn.LightOnCommond    com.cjn.LightOffCommond
    [slot 1] com.cjn.LightOnCommond    com.cjn.LightOffCommond
    [slot 2] com.cjn.NoCommand    com.cjn.NoCommand
    [slot 3] com.cjn.NoCommand    com.cjn.NoCommand
    [slot 4] com.cjn.NoCommand    com.cjn.NoCommand
    [slot 5] com.cjn.NoCommand    com.cjn.NoCommand
    [slot 6] com.cjn.NoCommand    com.cjn.NoCommand
    
    Living Room light on...
    Living Room light off...
    Kitchen light on...
    Kitchen light off...