前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >常用设计模式——命令模式

常用设计模式——命令模式

作者头像
用户5325874
发布2020-01-16 18:02:58
3430
发布2020-01-16 18:02:58
举报
文章被收录于专栏:用户5325874的专栏

命令模式

定义

将"请求"封装成对象,以便使用不同的请求、队列、或者日志来参数化其他对象(就是命令对象拥有相同的接口,不同的命令对象可以被设置到调用者中)。命令模式也可以支持撤销操作。

  • 一个命令对象将动作和接受者封装到命令对象中,这个对象只保留出一个execute()方法,当此方法被调用时,接收者就会进行这些动作。从外面看,其他对象不知道究竟哪个接收者进行了哪些动作。
  • 一个调用者可以设置不同的请求。
  • 命令模式将发出请求的对象和接收请求的对象解耦。被解耦的两者是通过命令对象进行沟通的,命令对象封装了接收者和动作(1个或多个)。
  • 调用者通过调用命令对象的execute()发出请求,这会使得接收者的动作被调用。
  • 调用者可以接受命令对象当做参数,甚至在运行时设置不同的命令对象。
  • 命令对象可以支持撤销,通过实现undo()方法,让系统回到execute()执行之前的状态

示例

代码语言:javascript
复制
/**
 * SimpleRemoteControlTest是命令模式的客户client
 * @author huangy on 2019-05-25
 */
public class SimpleRemoteControlTest {

    public static void main(String[] args) {

        // 遥控器就是调用者
        SimpleRemoteControl simpleRemoteControl = new SimpleRemoteControl();

        Light ligh = new Light();
        LightOnCommand lightOnCommand = new LightOnCommand(ligh);

        // 把命令传递给调用者
        simpleRemoteControl.setSlot(lightOnCommand);

        // 模拟按下按钮
        simpleRemoteControl.buttonWasPressed();
    }


}
代码语言:javascript
复制
/**
 * 简单遥控器
 * @author huangy on 2019-05-25
 */
public class SimpleRemoteControl {

    // 插槽
    Command slot;

    // 把命令对象设置到插槽上面
    public void setSlot(Command slot) {
        this.slot = slot;
    }

    public void buttonWasPressed() {
        slot.execute();
    }
}
代码语言:javascript
复制
/**
 * 所有命令对象的通用接口
 * @author huangy on 2019-05-25
 */
public interface Command {

    /**
     * 执行命令
     */
    void execute();

}
代码语言:javascript
复制
/**
 * @author huangy on 2019-05-25
 */
public class LightOnCommand implements Command {

    public LightOnCommand(Light light) {
        this.light = light;
    }

    /**
     * 电灯
     * 动作的接收者
     */
    private Light light;

    @Override
    public void execute() {
        light.on();
    }
}
代码语言:javascript
复制
/**
 * 电灯
 * @author huangy on 2019-05-25
 */
public class Light {

    public void on() {
        System.out.println("Light on");
    }

}

宏命令

宏命令是命令的简单延伸,允许调用多个命令,并且支持撤销。

代码语言:javascript
复制
/**
 * 宏命令
 * @author huangy on 2019-05-25
 */
public class MacroCommand implements Command {

    Command[] commands;

    Deque<Command> deque;

    public MacroCommand(Command[] commands) {
        this.commands = commands;
        deque = new LinkedList<>();
    }

    @Override
    public void execute() {
        for (Command command : commands) {
            command.execute();
            deque.push(command);
        }
    }

    @Override
    public void undo() {
        while (!deque.isEmpty()) {
            // 利用栈实现撤回
            Command command = deque.pop();
            command.undo();
        }
    }
}

用途

队列请求

将命令对象放到队列中,然后另外一个线程从队列中获取命令对象,并且执行excute()方法

Snip20190526_2
Snip20190526_2

日志请求

把系统每一个动作当成命令对象,存储在磁盘中,一旦系统死机,可以将命令对象重新加载,并成批依次调用这些对象execute()方法。

命令也可以用来实现日志和事务系统。

命令模式如何应用在事务中?

Snip20190526_1
Snip20190526_1
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 命令模式
    • 定义
      • 示例
        • 宏命令
          • 用途
            • 队列请求
            • 日志请求
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档