zoukankan      html  css  js  c++  java
  • 设计模式——命令模式

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

        其实简单的说,命令模式就是把方法调用封装起来了,通过封装方法调用,可以把运算块包装成型,所以调用此运算的对象不需要关心事情是如何进行的,只要知道如何使用包装成型的方法来完成它就可以。

        命令模式的使用场景:当需要将发出请求的对象和执行请求的对象解耦的时候,请考虑使用命令模式吧。

        场景举例:设计一款多功能遥控器,该遥控器可以控制家里各个电器的状态,例如电灯的开关,电视的开关,电扇的速度,车库门的开关等等,下面使用命令模式实现这个遥控器。在这里,发出请求的对象是遥控器,执行请求的对象是各种电器。

        首先需要让所有的命令对象实现同一个命令接口

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

         接口中有两个方法,一个是执行动作的方法execute,一个是撤销动作的方法undo

        下面实现电灯打开关闭命令前先声明一个电灯类

    public class Light {
        
        protected void on() {
            System.out.println("light is on");
        }
    
        protected void off() {
            System.out.println("light is off");
        }
    }

        电灯类只有两个方法on—>打开,off—>关闭;然后实现打开电灯的命令

    public class LightOnCommand implements Command {
    
        Light light;
    
        public LightOnCommand(Light light) {
            // TODO Auto-generated constructor stub
            this.light = light;
        }
    
        @Override
        public void execute() {
            // TODO Auto-generated method stub
            light.on();
        }
    
        @Override
        public void undo() {
            // TODO Auto-generated method stub
            light.off();
        }
    
    }

        注意undo的操作正好是与execute的操作相反的;在写一个电灯关闭的命令

    public class LightOffCommand implements Command {
    
        Light light;
    
        public LightOffCommand(Light light) {
            // TODO Auto-generated constructor stub
            this.light = light;
        }
    
        @Override
        public void execute() {
            // TODO Auto-generated method stub
            light.off();
        }
    
        @Override
        public void undo() {
            // TODO Auto-generated method stub
            light.on();
        }
    
    }

        再增加一个车库门的开启和关闭

    public class GarageDoor {
        public void up() {
            System.out.println("the garagedoor is up!");
        }
    
        public void down() {
            System.out.println("the garagedoor is down!");
        }
    
        public void lightOn() {
            System.out.println("the garagedoor's light is on!");
        }
    
        public void lightOff() {
            System.out.println("the garagedoor's light is off!");
        }
    }
    public class GarageDoorOpenCommand implements Command {
        GarageDoor garageDoor;
    
        public GarageDoorOpenCommand(GarageDoor garageDoor) {
            // TODO Auto-generated constructor stub
            this.garageDoor = garageDoor;
        }
    
        @Override
        public void execute() {
            // TODO Auto-generated method stub
            garageDoor.up();
            garageDoor.lightOn();
        }
    
        @Override
        public void undo() {
            // TODO Auto-generated method stub
            garageDoor.down();
            garageDoor.lightOff();
        }
    
    }
    public class GarageDoorCloseCommand implements Command {
        GarageDoor garageDoor;
    
        public GarageDoorCloseCommand(GarageDoor garageDoor) {
            // TODO Auto-generated constructor stub
            this.garageDoor = garageDoor;
        }
    
        @Override
        public void execute() {
            // TODO Auto-generated method stub
            garageDoor.down();
            garageDoor.lightOff();
        }
    
        @Override
        public void undo() {
            // TODO Auto-generated method stub
            garageDoor.up();
            garageDoor.lightOn();
        }
    
    }

        然后就是遥控器的实现了

    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;
        }
    
        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 class NoCommand implements Command {
    
        @Override
        public void execute() {
            // TODO Auto-generated method stub
            System.out.println("no command!");
        }
    
        @Override
        public void undo() {
            // TODO Auto-generated method stub
            
        }
    
    }

        开始测试一下遥控器

    public class RemoteLoader {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            RemoteControl remoteControl=new RemoteControl();
            Light light=new Light();
            LightOnCommand lightOn=new LightOnCommand(light);
            LightOffCommand lightOff =new LightOffCommand(light);
            
            GarageDoor garageDoor=new GarageDoor();
            GarageDoorOpenCommand garageDoorOpen=new GarageDoorOpenCommand(garageDoor);
            GarageDoorCloseCommand garageDoorClose=new GarageDoorCloseCommand(garageDoor);
            
            remoteControl.setCommand(0, lightOn, lightOff);
            remoteControl.setCommand(1, garageDoorOpen, garageDoorClose);
            
            remoteControl.onButtonWasPushed(0);
            remoteControl.onButtonWasPushed(1);
            remoteControl.offButtonWasPushed(0);
            remoteControl.offButtonWasPushed(1);
        }
    
    }

        打印结果:

    light is on
    the garagedoor is up!
    the garagedoor's light is on!
    light is off
    the garagedoor is down!
    the garagedoor's light is off!

        遥控器实现完毕,测试一下撤销命令

    public class RemoteLoader {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            RemoteControl remoteControl=new RemoteControl();
            Light light=new Light();
            LightOnCommand lightOn=new LightOnCommand(light);
            LightOffCommand lightOff =new LightOffCommand(light);
            
            remoteControl.setCommand(0, lightOn, lightOff);
            
            remoteControl.onButtonWasPushed(0);
            System.out.println("****************");
            remoteControl.undoButtonWasPushed();
        }
    
    }

        打印结果

    light is on
    ****************
    light is off

        总结:

        (1)命令模式将发出请求的对象和执行请求的对象解耦;

        (2)在被解耦的两者之间是通过命令对象进行沟通的。命令对象封装了接受者和一个或一组动作。

        (3)调用者通过调用命令对象的execute()发出请求,这会使得接受者的动作被调用。

        (4)调用者可以接受命令当作参数,甚至在运行时动态的进行。

        (5)命令可以支持撤销,做法是实现一个undo()方法来回到上一个execute()被执行前的状态。

       

  • 相关阅读:
    CodeForces 219D Choosing Capital for Treeland (树形DP)
    POJ 3162 Walking Race (树的直径,单调队列)
    POJ 2152 Fire (树形DP,经典)
    POJ 1741 Tree (树的分治,树的重心)
    POJ 1655 Balancing Act (树的重心,常规)
    HDU 2196 Computer (树形DP)
    HDU 1520 Anniversary party (树形DP,入门)
    寒门子弟
    JQuery选择器(转)
    (四)Web应用开发---系统架构图
  • 原文地址:https://www.cnblogs.com/shiwei-bai/p/5066824.html
Copyright © 2011-2022 走看看