专栏首页用户5325874的专栏常用设计模式——命令模式

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

命令模式

定义

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

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

示例

/**
 * 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();
    }


}
/**
 * 简单遥控器
 * @author huangy on 2019-05-25
 */
public class SimpleRemoteControl {

    // 插槽
    Command slot;

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

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

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

}
/**
 * @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();
    }
}
/**
 * 电灯
 * @author huangy on 2019-05-25
 */
public class Light {

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

}

宏命令

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

/**
 * 宏命令
 * @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()方法

日志请求

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

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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 常用设计模式——装饰模式

    装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者模式提供了比继承更有弹性的方案

    用户5325874
  • 常用设计模式——复合模式

    视图:用来呈现模型。视图通常直接从模型中取得它需要显示的状态和数据。视图使用组合模式实现用户界面,用户界面通常组合了嵌套的组件,像面板、框架和按钮。

    用户5325874
  • 常用设计模式——迭代器模式

    用户5325874
  • 设计之禅——我只要结果(命令模式)

    生活中我们会接收到各种各样的命令,也会发出各种各样的命令,虽然命令的事情都各不相同,但是都具有一个共同的特质,那就是对于发出命令的人而言他不需要知道你是怎么实现...

    夜勿语
  • Java设计模式-命令模式

    在对象的结构和创建问题都解决了之后,就剩下对象的行为问题了: 如果对象的行为设计的好,那么对象的行为就会更清晰,它们之间的协作效率就会提高. 行为型模式共有1...

    Java帮帮
  • Java设计模式之装饰模式

    Ladies and gentlemen,May I get your attention,Please?,Now I’m going to talk abou...

    CoderJed
  • 命令模式

    一、简介 1、命令模式将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。 2、命令模式中的几个...

    用户1215536
  • 迪米特法则与重构

    在面向对象设计的世界里,有一个寻常却又常常为人所忽略的原则——“迪米特(Law of Demeter)”法则。这个原则认为,任何一个对象或者方法,它应该只能调用...

    张逸
  • Android深入(三)-设计模式之简单工厂模式

    概念:简单工厂模式通俗的讲就是一个类的工厂,用于生产类,而这个工厂本身就是一个类,他可以创建多个类的实例。

    热心的程序员
  • java求百分比

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    逝兮诚

扫码关注云+社区

领取腾讯云代金券