命令行为模式(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包含了自己的边界和我希望用命令操作的控件的信息。 <  
1/2 1 2 下一页 尾页 |