转自:http://alaric.iteye.com/blog/1927894
命令(Command)模式:又称Action模式或者Transaction模式。它属于对象的行为模式。命令模式把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和撤销功能。
GoF命令模式结构图如下:
命令模式是有以下角色:
抽象命令(Command)角色:声明执行操作的接口。
具体命令(ConcreteCommand)角色:将一个接收者对象绑定到一个动作上。调用接收者相应的操作,以实现Execute方法。
客户端(Client)角色:创建一个命令对象并设定它的接收者。
请求者(Invoker)角色:负责调用命令对象的执行请求;
接收者(Receiver)角色:负责具体实施和执行一个请求相关的操作。任何一个类都可以作为一个接收者。
上面模型的模拟代码如下:
1、命令模式使新的命令在不改变现有结构代码的情况下很容易被加入到系统里;
2、允许接收请求的一方决定是否否决请求;
3、能较容易地设计一个命令队列;
4、可以容易地实现对请求的Undo和Redo操作;
5、在需要的情况下以较容易地将命令记入日志。
在讲门面模式的时候曾经提过一个例子,我们小时玩过投币的那种游戏机,一个方向操作杆,四个动作按钮,在一个操作面板上,封装了复杂的逻辑在机器内部,提供简单的操作界面,是一个门面的例子,然而每个操作发出一个命令,来控制游戏人物的运动和各种动作。方向操作杆是一个移动的命令,传入移动的方向和距离作为参数,还有出拳按键发出出拳命令,脚踢按键发出脚踢的命令,那还有组合操作命令,比如下踢腿(操作杆向下和踢脚按钮按下)。现在我们用命令模式来模拟这个场景。类的模型图如下:
如上图所示:Client相当于小时候的我们,Control相关于控制执行器,我们可以控制踢(KickCommand)、打(FistCommand)、移动(MoveCommand),这些命令的最终实现者也是接收者是游戏机(GameMachine)。
代码如下:
通过上面代码可以看出,本来客户端可以直接调用接收者来执行动作的,现在在中间引入了命令,这些命令由调用者(Invoker这里是Control)来调用,从而对客户端和命令接收者解耦了,增加了命令后,使得命令除了execute方法外,可以插入很多其它动作,比如redo,undo,或者记录日志等。