在日常生活中,我们常常会遇到这样一些问题:需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活。
命令模式是非常实用的一个模式,比如最常用的就是我们编写项目中用到的撤销\恢复(Undo\Redo)就是通过命令模式(Command)来实现的;在如我们的计算器、小孩通过遥控器控制赛车运动,这些都是通过命令模式实现的,下面就详细讲解命令模式.
一.模式定义
命令模式(Command Pattern):将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作。命令模式是一种对象行为型模式.
在命令模式中发送者与接收者没有直接引用关系,发送请求的对象至需要知道如何发送请求,而不必知道如何完成请求,这就是命令模式的模式动机.
二.模式结构及组成
命令模式的结构图如下图所示:
其中命令模式的角色如下所示:
客户端(Client):创建一个具体的命令对象,并确定其接收者.
请求者(Invoker):负责发出命令请求.
接收者(Receiver):具体实施或执行一个请求.
抽象命令(Command):给出所有具体命令的抽象接口.
具体命令(ConcreteCommand):实现抽象命令的方法,负责调用接收者.
先举一个简单的例子:
1.玉帝下旨让太白金星去招悟空上天庭
在这个例子*有五个角色:命令角色:圣旨 ,具体命令角色:具体圣旨,立即上天庭报道,请求者角色:太白金星,接受者角色:美猴王,客户角色:Client玉帝.
它的模式图如下,这就是一个简单的命令模式的例子.
2.电视机遥控器
电视机是请求的接收者,遥控器是请求的发送者,遥控器上有一些按钮,不同的按钮对应电视机的不同操作。抽象命令角色由一个命令接口来扮演,有三个具体的命令类实现了抽象命令接口,这三个具体命令类分别代表三种操作:打开电视机、关闭电视机和切换频道。显然,电视机遥控器就是一个典型的命令模式应用实例。
接受者--Televison
1.降低对象之间的耦合度。
2.新的命令可以很容易地加入到系统中。
3.可以比较容易地设计一个组合命令。
4.调用同一方法实现不同的功能
5.可以用来做批处理操作
6.Undo\Redo操作
因为每一个命令都需要设计一个具体命令类,所以可能会导致系统有过多的具体命令类,影响使用。
最后,我这篇文章主要讲诉的是命令模式,并通过命令模式一些例子来叙述,同时该文章主要思想来自:作者Eastmount自己的思考,《大话设计模式》,《head first设计模式》等书,还有是清华大学的课件,以及一些其他人关于命令模式的博客文章,但由于作者的大意,找不到有些图来自哪?所以如果作者见到,请见谅,我主要是想分享自己的一些知识供大家学习和了解。如果有错误或不足之处,请读者原谅!!!
(By:Eastmount 2013-5-12-夜2点)