首页 > 代码库 > 设计模式之命令模式
设计模式之命令模式
介绍命令模式之前,来看看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 对象中的执行方法,进而调用业务层中的接收角色。这样就完成了请求的处理。
设计模式之命令模式