1-6 命令模式

定义

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

使用场景

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

基本框架

遥控器(调用者) <——-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服务器是怎样处理这种的队列方式? )

日志请求、或者事务处理

或者其他吧

发布了13 篇原创文章 · 获赞 10 · 访问量 1642

猜你喜欢

转载自blog.csdn.net/navigator2015/article/details/74052761
1-6