1-6 命令模式

来源:互联网 发布:windows哪个系统好用 编辑:程序博客网 时间:2024/06/11 06:58

    • 定义
    • 使用场景
    • 基本框架
    • 案例引入
      • 简例
      • 遥控器7个插槽再加上撤销按钮
      • 实现多层次的撤销操
      • 用party模式完善上述案例
    • 应用场景
      • 工作队列
      • 日志请求或者事务处理
      • 或者其他吧

定义

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

使用场景

    日志安排、线程池、队列请求、业务出现异常时的根据日志重新请求

基本框架

遥控器(调用者) <——-Command(具体命令)<——– Light(请求的接受者)

案例引入

制作一个控制器,有七个插槽,每个插槽有两个按钮的开、关按钮,并有整体的一个撤销按钮(撤销上一个操作)

简例

只一个厨房灯插槽的一个按钮(开灯按钮)

这里写图片描述

public class Light {    public void turnOn(){        System.out.println("打开灯");    }}public interface Command {    public void excute();}public class LightOnCommand implements Command {    //请求的接受者    private Light light;    public LightOnCommand(Light l){        this.light = l;    }    @Override    public void excute() {        light.turnOn();    }}public class SimpleRemoteControl {    //注入具体命令(将开灯请求封装成开灯命令),该命令中具体的请求执行者    private Command command;    public SimpleRemoteControl(Command command){        this.command = command;    }    public void setCommand(Command command){        this.command = command;    }    //遥控器的按钮操作    public void pressButton(){        command.excute();    }}public class RemoteControlTest {    public static void main(String[] args) {        Light light = new Light();        Command command = new LightOnCommand(light);        SimpleRemoteControl remoteControl = new SimpleRemoteControl(command);        remoteControl.pressButton();    }}

遥控器7个插槽、再加上撤销按钮

这里写图片描述

public class Light {    public void turnOn(){        System.out.println("打开灯");    }    public void turnOff(){        System.out.println("关灯");    }}public class LightOffCommand implements Command {    //请求的接受者    private Light light;    public LightOffCommand(Light l){        this.light = l;    }    @Override    public void excute() {        light.turnOff();    }}public class RemoteControl {    // 这两个数组来盛放7个插槽的开、关命令    private Command[] onCommands;    private Command[] offCommands;    // 标记上一个撤销命令    private Command undoCommand;    public RemoteControl(){        this.onCommands = new Command[7];        this.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] = onCommand;    }    public void pressOnButton(int slot){        onCommands[slot].excute();        undoCommand = onCommands[slot];    }    public void pressOffButton(int slot){        offCommands[slot].excute();        undoCommand = offCommands[slot];    }    //撤销    public void undoCommand(){        undoCommand.excute();    }}public class RemoteControlTest {    public static void main(String[] args) {        Light light = new Light();        TV tv = new TV();        Command lightOnCommand = new LightOnCommand(light);        Command lightOffCommand = new LightOffCommand(light);        Command tvOnCommand = new TVOnCommand(tv);        Command tvOffCommand = new TVOffCommand(tv);        RemoteControl remoteControl = new RemoteControl();        remoteControl.setCommands(0, lightOnCommand, lightOffCommand);        remoteControl.setCommands(1, tvOnCommand, tvOffCommand);        remoteControl.pressOnButton(0);        remoteControl.pressOffButton(0);        System.out.println("==============");        remoteControl.pressOnButton(1);        remoteControl.pressOffButton(1);        System.out.println("==============");        //执行撤销操作        remoreControl.undoComand();    }}

实现多层次的撤销操

将每次的命令操作都放在栈里,撤销的时候,从栈里取出最上层的命令
public class RemoteControl {    // 这两个数组来盛放7个插槽的开、关命令    private Command[] onCommands;    private Command[] offCommands;    // 定义一个栈 来保存每次的命令    private Stack<Command> undoCommandStack;    public RemoteControl(){        this.onCommands = new Command[7];        this.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] = onCommand;    }    public void pressOnButton(int slot){        onCommands[slot].excute();        //undoCommand = onCommands[slot];        undoCommandStack.add(onCommands[slot]);    }    public void pressOffButton(int slot){        offCommands[slot].excute();        //undoCommand = offCommands[slot];        undoCommandStack.add(offCommands[slot]);    }    //撤销    public void undoCommand(){        //undoCommand.excute();        if(!undoCommandStack.empty()){            Command undoCommand = undoCommandStack.pop();            undoCommand.excute();        }else{            syso("已经撤销了所有命令!");        }    }}

用party模式完善上述案例 ###

你想坐在沙发上吃着薯片舒适的看电视,但仅凭一个遥控器无法同时弄暗灯光、打开音响、电视等,还必须分别调好,遥控器也就失去了意义。将这一系列的命令封装起来,做成一个遥控器------即 party模式
public class MacroCommand implements Command{    private Command[] commands;    public MacroCommand(Command[] commands){        this.commands = commands;    }    @override    public void excute(){        for(int i =0; i< commands.lenght; i++){            commands[1].excute();        }    }}

应用场景

工作队列

线程池或者其他工作队列,可以在一个线程同步或者多个线程一部执行工作队列.(web服务器是怎样处理这种的队列方式? )

日志请求、或者事务处理

或者其他吧