命令行为模式(command behavior pattern)允许你在表现层(presentation layer)封装行为,使得采用自己喜欢的方法组织、跟踪、撤销和调用这些行为更加容易。
在现实生活中,次序是难以控制的。一旦某种东西处于运动状态,我们就很难操作这种动作的离散部分。当然,在现实生活中是不可能撤销某种动作的。但是在编程过程中,次序却不是难以琢磨的。如果你的计划是正确的,你就可以定义行动,接着用你喜欢的方式来控制这些行动。实现这种操作的一个非常有用的工具是命令行为(command behavior)模式。
命令行为模式是我们可以使用的一种简单模式。它在行为(action)概念的具体化和撤销行为方面显得尤其有益。把行为转换到对象中也是一条非常有序的途径,它可以确保每个操作都会集中在实现该操作的一部分代码上。
在本文中我们将研究命令行为模式的使用方法,你会感觉它比较有趣。我给窗体添加了一个球的图片,并且实现了表现球的移动过程的命令。每个球命令都被放入栈中,允许你撤销球的移动,或者重新查看球的移动。在稍微修补一下代码之后,你可以发现把表现层(gui)的操作转换为命令对象使得我们使用多种方式(例如按钮和菜单)封装、组织、跟踪、撤销和调用操作容易多了。
定义命令(command)类
实现命令行为的一个普通的途径是定义一个带有do和undo方法的基类(或接口)。undo执行与do操作相反的行为。do操作是什么样子都无关紧要,它可以是任何东西("do"在vb6中是保留字,因此我把"execute"作为方法的名字)。
我的例子实现了四个移动命令。每个命令从上下左右四个方向中选择一个方向执行移动操作。每个命令的undo操作采用相反的方向调用移动操作。很明显,我并没有限定两维的、直线方向。我可以模拟三维的或者三角法(trigonometric)运算规则的基本移动。现在我聚焦于该命令类。
使用公用基类的原因在于代码可以多形态地(polymorphically)调用do或undo操作,而不用关心命令对象的特定实例。列表1显示了基本的命令和所有四个衍生命令类的实现。由于vb6不支持类继承,我就使用了接口继承。
列表1
| ' icommand.cls public sub execute() end sub public sub undo() end sub public property set form(byval form as form1) end property ' downcommand.cls option explicit implements icommand private fform as form1 private sub icommand_execute() fform.movedown end sub private sub icommand_undo() fform.moveup end sub ' leftcommand.cls public property set icommand_form(byval form as form1) set fform = form end property option explicit implements icommand private fform as form1 private sub icommand_execute() fform.moveleft end sub private sub icommand_undo() fform.moveright end sub public property set icommand_form(byval form as form1) set fform = form end property ' rightcommand.cls option explicit implements icommand private fform as form1 private sub icommand_execute() fform.moveright end sub private sub icommand_undo() fform.moveleft end sub public property set icommand_form(byval form as form1) set fform = form end property ' upcommand.cls option explicit implements icommand private fform as form1 private sub icommand_execute() fform.moveup end sub private property set icommand_form(byval rhs as form1) set fform = rhs end property private sub icommand_undo() fform.movedown end sub |
请注意在列表1中icommand使用了前缀i。这是接口的一个通俗的前缀符号,在多种语言中被广泛的应用。它的目的是帮助读者记住该模块只包含定义。同时还要注意所有的方向命令中都使用了implements语句。这确保了每个类最少拥有icommand接口。其结果是我可以定义一个icommand变量,并给它指定实现了icommand类的任何实例。
最后我还要指出,每个命令都保持了特定的form(form1)的指针。其原因在于form1包含了自己的边界和我希望用命令操作的控件的信息。
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器