命令,出现在计算机中,是早就有的事,最典型的DOS系统就是命令模式最好的示例,大家输入一条指令给系统,系统就会完成一种操作,记得最早接触电脑时就是在初中的时候,Dos系统,没有鼠标,那个时候会电脑的人很少,完全明白电脑的老师就更是少得可怜,而且听说老师当时的工资是很多,受全校的尊敬。真是两重天啊,现在别说老师,就是真正的以电脑为生得人也难得生活了。
第一学期学校的电脑还没买来,老师讲的时Window95,每周都是只能一头雾水都听老师讲那些总让人想睡觉的操作,不过当时我还是以顽强的毅力将笔记记了厚厚的一本,后来第二学期,学校从一个单位里买来一些二手的电脑,Windows操作系统造价太贵,所以装得都是Dos。这下真是让我恼火,不说那些辛苦的笔记,因为讲得东西和实际操作的完全不搭边,老师也无可奈何,只能一个一个的将指令,但是老师的技术是在不敢恭维。
我当时根本不知道,什么电脑的历史,什么操作系统,说白了是完全不懂,甚至我还不知道,鼠标是什么东西。
只知道,在键盘里输入几个字就可以打开一个漂亮的图片,然后上面掉下来各个字母,我按一个键就可以消灭一个。(其实就是个打字游戏)。所以当时的电脑课基本是和没上差不多,打字,老师也不知道什么正确的姿势,连她自己也是一指禅打字。
这件事正好是一个命令模式的体现,一个完整的命令模式肯定具有以下角色。
- 客户(Client)角色:发出一个具体的命令。
- 命令执行者(Invoker)角色:负责执行客户端的指令。
- 命令(Command)角色:一个抽象角色,主要是定义的所有命令的统一接口。
- 具体命令(ConcreateCommand)角色:Command角色的实现类。
- 接受者(Receiver)角色:执行Command,完成Command指示的操作。
在上面举得例子中各个角色如下:
- 客户角色:就是我,我可以发出一个指令给计算机,比如“DIR”指令;
- 命令执行者:键盘,可以执行我的指令。
- 命令角色:即键盘的按键。
- 具体命令角色:即键盘的具体的按键,比如“D”."I","R"键
- 接受者:即主机,主机执行将键盘的命令完成具体的操作,到最后驱动显示器显示结果
再来一个阎宏老师《java与设计模式》的一个示例:
这是一个非常好的示例,Jolia,在操作他得音乐播放器在Command模式下的角色有如下所示:
客户端(client):女孩jolia
命令执行者:即音乐播放器的键盘:Keybord类
命令:即抽象的按键类,Command类,MecroCommand
具体命令:具体按键,PlayCommand,StopCommand,RewindCommand类
接收者:音乐播放器本身,AudioPlayer.
PureMVC在执行组件的命令时,也是采用的Command设计模式,因为在自定义的事件中对一个资源可能有多种操作,为了避免各个复杂操作间引起混乱,所以引入了Command模式。PureMVC中使用默认实现的SimpleCommand,同时继承了INotifier,所以此时他同时也是消息的通知者,拥有了Notifer的所有方法这可以降低Command与其他组件的关系如下所示:
public class SimpleCommand extends Notifier implements ICommand, INotifier
PureMVC中的命令有个MecroCommand类,此类是Command模式与合成模式的一个结合,它负责将一组命令,合成到一个命令中执行,类似于“批处理”,可以同时完成多条命令。PureMVC中Command模式的各个角色如下所示:
- 客户(Client)角色:Facade组件,负责发送指令。
- 命令执行者(Invoker)角色:Controller组件,执行Facade发送的指令。
- 命令(Command)角色:ICommand一个抽象角色,主要是定义的所有命令的统一接口。
- 具体命令(ConcreateCommand)角色:SimpleCommand,MecroCommand以及自定义的Command。
- 接受者(Receiver)角色:执行Command,完成Command指示的操作,即最终的View组件
命令模式可以带来很多方便通常在以下情况中使用:
1.同一个子系统拥有多个操作,且操作时牵涉的其他类比较多,而且,每个操作做都有较大的不同。
2.同一个资源的调用比较复杂,且操作可以抽象。