background image

 
图二:Command

 

模式的类图

   
 

 

而 对于请求的处理又有两种不同的方法,一种是 Command 只充当代理,将请求转发给某
个接受者对象,还有一种是 Command

 

对象自己处理完所有的请求操 作。当然,这只是两个

极端,更多的情况是 Command 完成一部分的工作,而另外的一部分这则交给接受者对象来

 

处理。
 
在新的 JDK

 

的 代理事件模型中,就可以看作是这样的一个 Command 模式。在那个模型中,

一个事件监听者类 EventListener

 

监听某个事件,并根据接口定义, 实现特定的操作。比如,

当用 Document 对象的 addDocumentListener(DocumentListener listener) 方法注册了
一个 DocumentListener 后,以后如果在 Document 对象中发生文本插入的事件,
DocumentListener

 

中实现的 insertUpdate(DocumentEvent e)方法就会被调用,如果发

生文本删除事件,removeUpdate(DocumentEvent e)方法就会被调用。怎么样,想想看,
这是不是一个 Command

 

模式的应用呢?

 
然而,最经典的 Command

 

模式的应用,莫过于 Swing 中的 Action 接口。Action 实际上继

承的是 ActionListener

 

,也就是说,它也是一个事件监听者 (EventListener)。但是

Action 作为一种 ActionListener 的扩展机制,提供了更多的功能。它可以在其中包含对这个 
Action 动作的一个或者多个文字的或图标的描叙,它提供了 Enable/Disable 的功能许可性
标志。并且,一个 Action

 

对象可以被多个 Invoker,比如实现相同功能的按钮,菜单,快捷

方式所共享。而这些 Invoker 都知道如何加入一个 Action,并充分利用它所提供的扩展机制。 
可以说,在这儿 Action 更像一个对象了,因为它不仅仅提供了对方法的实现,更提供了对方

 

 

法的描叙和控制。可以方便的描叙任何的事务,这更是面向对象方 法的威力所在。
 
下面我们看一个 Command 模式的应用的例子。假设要实现这样的一个任务:Task 
Schedule。也就是说,我想对多个任务进行安排,比如扫描磁盘,我希望它每 1 个小时进行

 

一次,而备份数据,我希望它半个小时进行一次,等等等等。但 是,我并不希望作为
TaskSchedule 的类知道各个任务的细节内容,TaskSchedule 应该只是知道 Task 本身,而

 

对具体的实现任务的细节 并不理会。因而在这儿,我们就需要对 TaskSchedule 和 Task 进行
解耦,将任务和具体的实现分离出来,这不正是 Command

 

 

模式的用武之地 吗?

 
 
图三:Command

 

模式的应用例子

   
 

 

程序清单:
 
//抽象的 Task 接口,作为回调的 Command

 

模式的主体

public interface Task { 
  public void taskPerform(); 

//具体的实现了 Task

 

接口的子类,实现特定的操作。