命令模式

来源:互联网 发布:python黑帽子 豆瓣 编辑:程序博客网 时间:2024/05/22 06:23
别名:Action动作模式,Transaction事务模式。我也叫它“参数回调模式”,因为本质上,命令模式和C的参数回调是一样的。
意图
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。
适用性
  • 抽象出待执行的动作以参数化某对象,你可用过程语言中的回调(c a l l b a c k )函数表达这种参数化机制。所谓回调函数是指函数先在某处注册,而它将在稍后某个需要的时候被调用。C o m m a n d 模式是回调机制的一个面向对象的替代品。
  • 在不同的时刻指定、排列和执行请求。一个C o m m a n d 对象可以有一个与初始请求无关的生存期。如果一个请求的接收者可用一种与地址空间无关的方式表达,那么就可将负责该请求的命令对象传送给另一个不同的进程并在那儿实现该请求。
  • 支持取消操作。C o m m a n d 的E x c u t e 操作可在实施操作前将状态存储起来,在取消操作时这个状态用来消除该操作的影响。C o m m a n d 接口必须添加一个U n e x e c u t e 操作,该操作取消上一次E x e c u t e 调用的效果。执行的命令被存储在一个历史列表中。可通过向后和向前遍历这一列表并分别调用U n e x e c u t e 和E x e c u t e 来实现重数不限的“取消”和“重做”。
(这是 指,备忘录模式中,撤销管理器通过方法的参数,把状态加到管理器中呢?!同时,容器中的所有状态都是一个接口的实现类,然后,都可以执行相同的方法:undo/redo。
 
  • 支持修改日志,这样当系统崩溃时,这些修改可以被重做一遍。在C o m m a n d 接口中添加装载操作和存储操作,可以用来保持变动的一个一致的修改日志。从崩溃中恢复的过程包括从磁盘中重新读入记录下来的命令并用E x e c u t e 操作重新执行它们。
  • 用构建在原语操作上的高层操作构造一个系统。这样一种结构在支持事务( t r a n s a c t i o n )的信息系统中很常见。一个事务封装了对数据的一组变动。C o m m a n d 模式提供了对事务进行建模的方法。C o m m a n d 有一个公共的接口,使得你可以用同一种方式调用所有的事务。同时使用该模式也易于添加新事务以扩展系统。
 
C++中STL和Boost等类库中广泛使用的仿函数类,也是命令模式的一种实现。
在面向过程编程语言,或者函数编程语言中,通过把函数指针作为函数的参数,可以实现参数回调。
在面向对象编程语言中,通过把某个仿函数接口的指针作为函数的参数,也可以实现类似于面向过程语言的函数参数的回调。
面向对象编程语言实现命令模式有几种变体。
如,可以把某个仿函数接口的指针作为类的一个实例变量保存在类中。

一、使用接口---实现类的方式。

  通常命令模式的接口中只有一个方法。

    实现类的方法有不同的功能,覆盖接口中的方法。

    在面向对象编程中,大量使用if…else…,或者switch…case…这样的条件选择语句是“最差实践”。通常这类代码,意味着有重构的余地。

命令模式就是干掉条件选择语句的利器。

1,首先提供一个接口:

public interface Command {

public void execute();

}

 

2,然后提供这个接口的实现类。每一个实现类的方法就是if…else…的一个代码块中的代码。

这样,调用方直接把一个具体类的实例传进来即可。如:

Public void test(Command para){

   Para.execute();

 

}

    即可,不需要再判断出现了哪种情况,应该执行哪一段代码。

一切的问题都由调用方处理。

如果不使用命令模式,那么如果情况逐步增多,如,从原来的2种,增加到20种,那么方法中的判断就会从1次增加到19次。

而使用命令模式,仅仅调用方需要从2个实现类增加到20个实现类即可。上面的test方法根本不需要做任何改变。

 

二、主要的用途是,使用参数回调模式。

   最主要使用命令模式的方式是使用参数回调模式。

命令接口作为方法的参数传递进来。然后,在方法体内回调该接口。

上文的例子是如此,Swing的事件机制也是使用这种方法。

如:

public interface Command {

public void execute();

}

 

public void actionPerformed(ActionEvent e) {

Command cmd = (Command)e.getSource();

cmd.execute();

}

 

当然,命令模式还可以使用其他方式来使用。不一定非用参数回调模式。

命令模式的核心思想是,带有某个方法的具体类的实例,作为接口传给使用方。对象的具体类型信息消失。

在使用方代码中拿到这个接口后调用这个接口的方法。

具体的执行效果,取决的命令发起人提供的对象是哪一个实现类的。这给了命令发起人完全的控制能力,而使用方代码不关心具体的命令类和方法。同时也使条件判断语句成为多余。

原创粉丝点击