设计模式之命令模式(三)

我回来啦!今天是周六,一看命令模式还有一个总结未完成,赶紧爬起来做做好。

就如上一篇所说的,如果拥有了一个遥控器,却无法光凭按下一个按你,就同时能弄暗灯光、打开音响和电视、设置到DVD,并让热水器开始加温,那么我要这个遥控器还有什么意义呢?

使用宏命令

根据比较高级的想法来看,就是我们需要制造一种新的命令,用来执行其他一堆命令,而不只是执行一个命令,这样就是一个不错的想法了吧。这就是我们将要说的宏命令。

public class MacroCommand implements Command {
    // 在宏命令中,用命令数组存储一大堆命令
Command[] commands;

public MacroCommand(Command[] commands) {
this.commands = commands;
}

public void execute() {
for (int i = 0; i < commands.length; i++) {
// 当这个宏命令被遥控器执行时,就一次性执行数组里的每个命令
commands[i].execute();
}
}

    /**
     * NOTE:  these commands have to be done backwards to ensure
     * proper undo functionality
     */
public void undo() {
for (int i = commands.length -1; i >= 0; i--) {
commands[i].undo();
}
}
}

让我们来看下如何使用宏命令:

  1. 先创建想要进入宏的命令集合
Light light = new Light("Living Room");
TV tv = new TV("Living Room");
Stereo stereo = new Stereo("Living Room");
Hottub hottub = new Hottub();

LightOnCommand lightOn = new LightOnCommand(light);
StereoOnCommand stereoOn = new StereoOnCommand(stereo);
TVOnCommand tvOn = new TVOnCommand(tv);
HottubOnCommand hottubOn = new HottubOnCommand(hottub);
  1. 接下来创建两个数组,其中一个用来记录开启命令,另一个用来记录关闭命令,并在数组内放入对应的命令
Command[] partyOn = { lightOn, stereoOn, tvOn, hottubOn};
Command[] partyOff = { lightOff, stereoOff, tvOff, hottubOff};

MacroCommand partyOnMacro = new MacroCommand(partyOn);
MacroCommand partyOffMacro = new MacroCommand(partyOff);
  1. 然后将宏命令指定给我们所希望的按钮:
remoteControl.setCommand(0, partyOnMacro, partyOffMacro);
  1. 最后,只需按下一些按钮,测试是否正常工作
System.out.println(remoteControl);
System.out.println("--- Pushing Macro On---");
remoteControl.onButtonWasPushed(0);
System.out.println("--- Pushing Macro Off---");
remoteControl.offButtonWasPushed(0);

不会忘记我们的撤销功能

public void undo() {
for (int i = commands.length -1; i >= 0; i--) {
commands[i].undo();
}
}

命令模式的更多用途:队列请求

命令可以将运算块打包(一个接收者和一组动作),然后将它传来传去,就像是一般的对象一样。现在,即使在命令被创建许久之后,运算依然可以被调用。事实上,它甚至可以在不同的线程中被调用。我们可以利用这样的特性衍生一些应用,例如:日程安排、线程池、工作队列等。

想象一个工作队列:你再某一端添加命令,然后另一端则是线程。线程进行下面的动作:从队列中取出一个命令,调用它的execute()方法,等待这个调用完成,然后将此命令对象丢弃,再取出下一个命令。。。

请注意,工作队列类和进行计算的对象之间完全是解耦的。此刻线程可能在进行财务运算,下一刻却在读取网络数据。工作队列对象不在乎到底做些什么,他们只知道取出命令对象,然后调用其execute()方法。

命令模式的更多用途:日志请求

某些应用需要我们将所有的动作都记录在日志中,并能在系统死机之后,重新调用这些动作恢复到之前的状态。命令模式能够支持这一点。

当我们执行命令的时候,将历史记录存储在磁盘中,一旦系统死机,我们就可以将命令对象重新加载,并成批地依次调用这些对象的execute()方法。

比如有许多调用大型数据结构的应用无法在每次改变发生时被快速地存储。通过使用记录日志,我们可以将上次检查点之后的所有操作记录下来,如果系统出状况,从检查点开始应用这些操作。比如说,对于电子表格应用,我们可能想要实现的错误回复方式是将电子表格的操作记录在日志中,而不是每次电子表格一有变化就记录整个电子表格。

对于更高级的应用而言,这些技巧可以被扩展应用到事务处理中,也就是说,一整群操作必须全部进行完成,或者没有进行任何的操作

设计箱内的工具

还是按照之前的套路,总结下工具箱内新增的工具吧

  • OO基础

    抽象、封装、继承、多态

  • OO原则

    封装变化

    多用组合,少用继承

    针对接口编程,不针对实现编程

    为交互对象之间的松耦合设计而努力

    依赖抽象,不要依赖具体类

    类应该对扩展开放,对修改关闭

  • OO模式

    『策略模式』、『观察者模式』、『装饰者模式』、『抽象工厂模式』、『工厂方法模式』、『单例模式』

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

我们学习命令模式,就是一个循序渐进的过程,先从简单的开关开始,然后再到复杂的开启状态,进而想到队列,想到记录日志这种事务操作。学习也是一个循序渐进的过程,我们通过简单的Demo学习,然后到项目实践,再到后面独立设计框架,我相信大家都能悟出这个道理来。

持续学习,精进学习,我们会一起加油。下一次,我们将学习适配器模式与外观模式

爱生活,爱学习,爱感悟,爱挨踢

(0)

相关推荐

  • Oracle错误

    起源 今天跟往常一样,登陆PL/SQL,确登陆失败,出现一个错误"ORA-01034"和"ORA-27101"如图: 然后就就通过命令提示符去登陆Oracle, ...

  • Java设计模式【命令模式】

    命令模式 命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行.这个过程好在,三者相互解耦,任何一方都不 ...

  • PHP设计模式之命令模式

    PHP设计模式之命令模式 命令模式,也称为动作或者事务模式,很多教材会用饭馆来举例.作为顾客的我们是命令的下达者,服务员是这个命令的接收者,菜单是这个实际的命令,而厨师是这个命令的执行者.那么,这个模 ...

  • [PHP小课堂]PHP设计模式之命令模式

    [PHP小课堂]PHP设计模式之命令模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料

  • 图解Java设计模式之命令模式

    智能生活项目需求 命令模式基本介绍 命令模式的原理类图 命令模式在Spring框架中JdbcTemplate应用源码分析 命令模式的注意事项和细节 智能生活项目需求 看一个具体的需求 我们买类一套智能 ...

  • 设计模式之命令模式

    让我们从一个简单的项目(遥控器)了解命令模式,然后再给出他的定义: 此项目地址: https://github.com/Stray-Kite/Design-Pattern/tree/master/sr ...

  • 设计模式之命令模式(二)

    上一次留给大家去做的实践,不知道大家执行的怎么样了呢. 我们通过一个简单的练习,完成了一个控制开关.那现在,我们打算将遥控器的每个插槽,对应到一个命令这样就要遥控器变成"调用者". ...

  • 设计模式之命令模式(一)

    在本次学习过程中,我们把封装带到一个全新的境界:把方法调用(method invocation)封装起来.没错,通过封装方法调用,我们可以把运算块包装成形. 所以调用此运算的对象不需要关心事情是如何进 ...

  • java设计模式-命令模式(Command)

    定义命令模式属于对象的行为模式.命令模式又称为行动(Action)模式或者交易(Transaction)模式.命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化, ...

  • 设计模式(十五)——命令模式(Spring框架的JdbcTemplate源码分析)

    设计模式(十五)——命令模式(Spring框架的JdbcTemplate源码分析)