请求发送者与接收者解耦——命令模式(四)

转载 2013年12月06日 12:05:04

5 撤销操作的实现

       在命令模式中,我们可以通过调用一个命令对象的execute()方法来实现对请求的处理,如果需要撤销(Undo)请求,可通过在命令类中增加一个逆向操作来实现。

微笑

扩展

除了通过一个逆向操作来实现撤销(Undo)外,还可以通过保存对象的历史状态来实现撤销,后者可使用备忘录模式(Memento Pattern)来实现

       下面通过一个简单的实例来学习如何使用命令模式实现撤销操作:

       Sunny软件公司欲开发一个简易计算器,该计算器可以实现简单的数学运算,还可以对运算实施撤销操作。

       Sunny软件公司开发人员使用命令模式设计了如图5所示结构图,其中计算器界面类CalculatorForm充当请求发送者,实现了数据求和功能的加法类Adder充当请求接收者,界面类可间接调用加法类中的add()方法实现加法运算,并且提供了可撤销加法运算的undo()方法。

5  简易计算器结构图

       本实例完整代码如下所示:

[java] view plaincopy
  1. //加法类:请求接收者  
  2. class Adder {  
  3.     private int num=0//定义初始值为0  
  4.       
  5.     //加法操作,每次将传入的值与num作加法运算,再将结果返回  
  6.     public int add(int value) {  
  7.         num += value;  
  8.         return num;  
  9.     }  
  10. }  
  11.   
  12. //抽象命令类  
  13. abstract class AbstractCommand {  
  14.     public abstract int execute(int value); //声明命令执行方法execute()  
  15.     public abstract int undo(); //声明撤销方法undo()  
  16. }  
  17.   
  18. //具体命令类  
  19. class ConcreteCommand extends AbstractCommand {  
  20.     private Adder adder = new Adder();  
  21.     private int value;  
  22.           
  23.     //实现抽象命令类中声明的execute()方法,调用加法类的加法操作  
  24. public int execute(int value) {  
  25.         this.value=value;  
  26.         return adder.add(value);  
  27.     }  
  28.       
  29.     //实现抽象命令类中声明的undo()方法,通过加一个相反数来实现加法的逆向操作  
  30.     public int undo() {  
  31.         return adder.add(-value);  
  32.     }  
  33. }  
  34.   
  35. //计算器界面类:请求发送者  
  36. class CalculatorForm {  
  37.     private AbstractCommand command;  
  38.       
  39.     public void setCommand(AbstractCommand command) {  
  40.         this.command = command;  
  41.     }  
  42.       
  43.     //调用命令对象的execute()方法执行运算  
  44.     public void compute(int value) {  
  45.         int i = command.execute(value);  
  46.         System.out.println("执行运算,运算结果为:" + i);  
  47.     }  
  48.       
  49.     //调用命令对象的undo()方法执行撤销  
  50.     public void undo() {  
  51.         int i = command.undo();  
  52.         System.out.println("执行撤销,运算结果为:" + i);  
  53.     }  
  54. }  

       编写如下客户端测试代码:

[java] view plaincopy
  1. class Client {  
  2.     public static void main(String args[]) {  
  3.         CalculatorForm form = new CalculatorForm();  
  4.         AbstractCommand command;  
  5.         command = new ConcreteCommand();  
  6.         form.setCommand(command); //向发送者注入命令对象  
  7.           
  8.         form.compute(10);  
  9.         form.compute(5);  
  10.         form.compute(10);  
  11.         form.undo();  
  12.     }  
  13. }  


        编译并运行程序,输出结果如下:

执行运算,运算结果为:10

执行运算,运算结果为:15

执行运算,运算结果为:25

执行撤销,运算结果为:15

 

疑问

思考

如果连续调用“form.undo()”两次,预测客户端代码的输出结果。

       需要注意的是在本实例中只能实现一步撤销操作,因为没有保存命令对象的历史状态,可以通过引入一个命令集合或其他方式来存储每一次操作时命令的状态,从而实现多次撤销操作。除了Undo操作外,还可以采用类似的方式实现恢复(Redo)操作,即恢复所撤销的操作(或称为二次撤销)。

微笑

练习

修改简易计算器源代码,使之能够实现多次撤销(Undo)和恢复(Redo)

 

【作者:刘伟   http://blog.csdn.net/lovelion

设计模式 之 命令模式

命令模式
  • icatchyou
  • icatchyou
  • 2014年08月08日 09:10
  • 384

C# 命令模式

一、命令模式:        将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。 ——《设计...
  • xunzaosiyecao
  • xunzaosiyecao
  • 2016年02月29日 20:26
  • 3176

设计模式读书笔记-----命令模式

在开发过程中,我可能会需要向某些对象发送一些请求,但是我们不知请求的具体接收者是谁,也不知道被请求的操作是那个,我们只知道在程序运行中指定具体的请求接收者即可。打个比方,电视遥控器,我们只需要知道按那...
  • chenssy
  • chenssy
  • 2013年07月20日 10:28
  • 3535

C++设计模式10--命令模式(二)(Command)--降低请求发送者与接收者耦合

工作了一天感觉好累,洗了个澡,打开电视看看有没有喜欢的节目,拿起遥控器,看着上面的按钮,忽然感觉好奇妙,我们按一开机键,电视就开了,然后...哈哈,真好玩,我按我按。细想之下这不就是一个命令模式么。 ...
  • gatieme
  • gatieme
  • 2014年01月09日 16:40
  • 18763

请求发送者与接收者解耦——命令模式

转:http://blog.csdn.net/lovelion/article/details/8796736
  • lynchyo
  • lynchyo
  • 2014年08月25日 14:24
  • 420

请求发送者与接收者解耦——命令模式

本文转载自 :http://blog.csdn.net/lovelion/article/details/8796736 装修新房的最后几道工序之一是安装插座和开关,通过开关可以控制...
  • yzf279533105
  • yzf279533105
  • 2016年01月03日 20:19
  • 187

请求发送者与接收者解耦——命令模式(一)

装修新房的最后几道工序之一是安装插座和开关,通过开关可以控制一些电器的打开和关闭,例如电灯或者排气扇。在购买开关时,我们并不知道它将来到底用于控制什么电器,也就是说,开关与电灯、排气扇并无直接关系,一...
  • LoveLion
  • LoveLion
  • 2013年04月15日 21:39
  • 14305

请求发送者与接收者解耦——命令模式(一)

装修新房的最后几道工序之一是安装插座和开关,通过开关可以控制一些电器的打开和关闭,例如电灯或者排气扇。在购买开关时,我们并不知道它将来到底用于控制什么电器,也就是说,开关与电灯、排气扇并无直接关系,一...
  • wangeclipse
  • wangeclipse
  • 2013年12月06日 12:03
  • 402

命令模式 -- 请求发送者与接收者解耦

装修新房的最后几道工序之一是安装插座和开关,通过开关可以控制一些电器的打开和关闭,例如电灯或者排气扇。在购买开关时,我们并不知道它将来到底用于控制什么电器,也就是说,开关与电灯、排气扇并无直接关系,一...
  • u013233468
  • u013233468
  • 2014年01月15日 22:27
  • 599

请求发送者与接收者解耦——命令模式(一)

装修新房的最后几道工序之一是安装插座和开关,通过开关可以控制一些电器的打开和关闭,例如电灯或者排气扇。在购买开关时,我们并不知道它将来到底用于控制什么电器,也就是说,开关与电灯、排气扇并无直接关系,一...
  • hsstc
  • hsstc
  • 2014年06月23日 16:02
  • 244
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:请求发送者与接收者解耦——命令模式(四)
举报原因:
原因补充:

(最多只允许输入30个字)