首页 > 代码库 > 设计模式之命令模式

设计模式之命令模式

  介绍命令模式之前,来看看Window的界面设计,同样的菜单控件,在不同的应用环境中的功能是完全不同的;而菜单选项的某个功能可能和鼠标右键的某个功能完全一致。按照最差、最原始的设计,这些不同功能的菜单、或者右键弹出菜单是要分开来实现的,你可以想象一下,word 文档上面的一排菜单要实现出多少个“形似神非”的菜单类来?这完全是行不通的。这时,就要运用分离变化与不变的因素,将菜单触发的功能分离出来,而制作菜单的时候只是提供一个统一的触发接口。这样修改设计后,功能点可以被不同的菜单或者右键重用;而且菜单控件也可以去除变化因素,很大的提高了重用;而且分离了显示逻辑和业务逻辑的耦合。这便是命令模式的雏形。

  命令模式就是一种从界面设计中提取出来的一种分离耦合,提高重用的方法。《设计模式》中命令模式的定义为:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。

  前面的引语倒是容易理解,这定义显得很晦涩,其实命令模式像很多设计模式一样——通过在你的请求和处理之间加上了一个中间人的角色,来达到分离耦合的目的。通过对中间人角色的特殊设计来形成不同的模式。当然命令模式就是一种特殊设计的结果。

  还是来看看命令角色的结构组成吧:

  

    1) 命令角色(Command):声明执行操作的接口。有java 接口或者抽象类来实现。
    2) 具体命令角色(Concrete Command):将一个接收者对象绑定于一个动作;调用接收者相应的操作,以实现命令角色声明的执行操作的接口。
    3) 客户角色(Client):创建一个具体命令对象(并可以设定它的接收者)。
    4) 请求者角色(Invoker):调用命令对象执行这个请求。
    5) 接收者角色(Receiver):知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者。

  同样,举个简单栗子。

  这里将以命令模式在Web 开发中最常见的应用——Struts 中Action 的使用作为例子。在 Struts 中Action 控制类是整个框架的核心,它连接着页面请求和后台业务逻辑处理。按照框架设计,每一个继承自Action 的子类,都实现execute 方法——调用后台真正处理业务的对象来完成任务。

 1 public class Action { 2     /* 3     *可以看出,Action 中提供了两个版本的执行接口,而且实现了默认的空实现。 4     */ 5     public ActionForward execute( ActionMapping mapping,ActionForm form,ServletRequest request,ServletResponse response)throws Exception { 6         try { 7             return execute(mapping, form, (HttpServletRequest) request,(HttpServletResponse) response); 8         } catch (ClassCastException e) { 9             return null;10         }11     }12     public ActionForward execute( ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response)throws Exception {13         return null;14     }15 }16 17 下面的就是请求者角色,它仅仅负责调用命令角色执行操作。18 public class RequestProcessor {19     protected ActionForward processActionPerform(HttpServletRequest request,HttpServletResponse response,Action action,ActionForm form,20 ActionMapping mapping)throws IOException, ServletException {21         try {22             return (action.execute(mapping, form, request, response));23         } catch (Exception e) {24             return (processException(request, response,e, form,mapping));25         }26     }27 }

  Struts 框架为我们提供了以上两个角色,要使用struts 框架完成自己的业务逻辑,剩下的三个角色就要由我们自己来实现了。步骤如下:
  1) 很明显我们要先实现一个 Action 的子类,并重写execute 方法。在此方法中调用业务模块的相应对象来完成任务。
  2) 实现处理业务的业务类,来充当接收者角色。
  3) 配置 struts-config.xml 配置文件,将自己的Action 和Form以及相应页面结合起来。
  4) 编写 jsp,在页面中显式的制定对应的处理Action。
  一个完整的命令模式就介绍完了。当你在页面上提交请求后,Struts 框架会根据配置文件中的定义, 将你的Action 对象作为参数传递给RequestProcessor 类中的processActionPerform()方法,由此方法调用Action 对象中的执行方法,进而调用业务层中的接收角色。这样就完成了请求的处理。

  

设计模式之命令模式