命令模式也是行为模式中的一种。它也被称为动作、事务、Action、Transaction、Command。
从它的别称可以看到,它和 VFP 中的命令有着完全不同的内涵。VFP 的命令是语言内置的完成一个动作的指令,而命令模式中的“命令”可以理解为是对一个或多个命令(宏命令)的描述。
在 VFP 中,以下的应用场景可能是最适用的:
按照标准的命令模式的说法,首先需要一个接口,在 VFP 中,也就是一个类模板:
Define Class ICommand As Custom
Procedure Execute()
Endproc
Enddefine
基于这个模板,可以对所执行的操作定义简单或者复杂的命令类:
Define Class SimpleCommand As ICommand
cCommand = ""
Procedure Init(tcCommand As String)
This.cCommand = m.tcCommand
Endproc
*** <summary>
*** 执行简单的命令
*** </summary>
Procedure Execute()
Evaluate(This.cCommand)
Endproc
Enddefine
Define Class ComplexCommand As ICommnad
*!* 一些在命令执行过程中需要使用的参数或者对象
oReceiver = .null.
cPara1 = ""
cPara2 = .F.
cPara3 = {^2020-01-01}
Procedure Init(toReceiver As Object, tcString As String, tlLogic As Logical, tdDate As Date)
With This
.oReceiver = m.toReceiver
.cPara1 = m.tcString
.cPara2 = m.tlLogic
.cPara3 = m.tdDate
Endwith
Endproc
Procedure Execute()
This.oReceiver.DoSomething(This.cPara1)
This.oReceiver.DoSomething2(This.cPara2)
This.oReceiver.DoSomething3(This.cPara3)
This.oReceiver.DoSomething4()
Endproc
Enddefine
在上面的代码中,ComplexCommand 类的 oReceiver 熟悉所存储的对象,在命令模式中称之为“接收者”。与之对应的,自然存在一个“调用者”。但是,“调用者”是必须存在的,而“接收者”则未必需要存在。
我们先定义好一个“接收者”:
Define Class Receiver As Custom
Procedure DoSomething(tcString As String)
*!* 接收参数,执行一些操作
Endproc
Procedure DoSomething2(tlLogic As Logical)
*!* 接收参数,执行一些操作
Endproc
Procedure DoSomething3(tdDate As Date)
*!* 接收参数,执行一些操作
Endproc
Procedure DoSomething4()
*!* 执行一些操作
Endproc
Enddefine
至此,可以看到,命令模式似乎对复杂“命令”的场景下似乎有存在的必要,在简单命令的场景下似乎多此一举。对于简单命令这种场景,它的存在也许仅有以下的意义:
最后,我们需要一个“调用者”:
Define Class Invoker As Custom
oFirst = .NULL.
oSecond = .NULL.
PROCEDURE SetFirst(toObject As ICommand)
This.oFirst = m.toObject
EndProc
Procedure SetSecond(toObject As ICommand)
This.oSecond = M.toObject
EndProc
Procedure DoSomething()
With This
If Vartype(.oFirst) = "O"
.oFirst.Excute()
EndIf
If Vartype(.oSecond) = "O"
.oSecond.Excute()
EndIf
EndWith
EndProc
EndDefine
那么,“当你点击菜单项或者按钮”时的代码是什么样的呢?