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

撤销操作的实现

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

微笑

扩展

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

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

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

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

5  简易计算器结构图

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

[java]   view plain  copy
  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 plain  copy
  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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值