1700463657
//被要求修改功能
1700463658
1700463659
public abstract void change();
1700463660
1700463661
//被要求给出所有的变更计划
1700463662
1700463663
public abstract void plan();
1700463664
1700463665
//每个接收者都要对直接执行的任务可以回滚
1700463666
1700463667
public void rollBack(){
1700463668
1700463669
//根据日志进行回滚
1700463670
1700463671
}
1700463672
1700463673
}
1700463674
1700463675
仅仅增加了一个rollBack的方法,每个接收者都可以对自己实现的任务进行回滚。怎么回滚?根据事务日志进行回滚!新增加的一个命令CancelDeletePageCommand实现撤销刚刚发出的删除命令,如代码清单15-21所示。
1700463676
1700463677
代码清单15-21 撤销命令
1700463678
1700463679
public class CancelDeletePageCommand extends Command{
1700463680
1700463681
//撤销删除一个页面的命令
1700463682
1700463683
public void execute(){
1700463684
1700463685
super.pg.rollBack();
1700463686
1700463687
}
1700463688
1700463689
}
1700463690
1700463691
然后就是用Invoker进行调用了,客户选择了执行这个撤销动作,就可以进行撤销操作,该示意代码确实比较简单,真正实现起来那是异常复杂的,为什么呢?事务日志处理是非常繁琐的处理机制,想想数据库的日志处理吧,你就能想象出这个日志有多复杂!
1700463692
1700463693
1700463694
1700463695
1700463697
设计模式之禅 15.5 最佳实践
1700463698
1700463699
各位读者可能已经发觉了这样的问题:在我们旅行社的例子中,我们的Receiver角色(也就是Group的三个实现类)并没有暴露给Client,而在通用的类图和源码中却出现了Client类对Receiver角色的依赖,这是为什么呢?
1700463700
1700463701
如果你发现了这个问题,则说明你阅读得非常仔细,好习惯!每一个模式到实际应用的时候都有一些变形,命令模式的Receiver在实际应用中一般都会被封装掉(除非非常必要,例如撤销处理),那是因为在项目中:约定的优先级最高,每一个命令是对一个或多个Receiver的封装,我们可以在项目中通过有意义的类名或命令名处理命令角色和接收者角色的耦合关系(这就是约定),减少高层模块(Client类)对低层模块(Receiver角色类)的依赖关系,提高系统整体的稳定性。因此,建议大家在实际的项目开发时采用封闭Receiver的方式(当然了,仁者见仁,智者见智),减少Client对Reciver的依赖,该方案只是对Commandd抽象类及其子类有一定的修改,Command类如代码清单15-22所示。
1700463702
1700463703
代码清单15-22 完美的Command类
1700463704
1700463705
public abstract class Command{
1700463706
[
上一页 ]
[ :1.700463657e+09 ]
[
下一页 ]