说实话,我现在还没有很好地理解命令模式,我只能结合例子谈谈我现在的认识和理解。
按照GoF的解释,命令模式是将一个请求封装成一个对象的方式,在过程型编程语言中,我们通常用一个回调函数来表示一个请求,这样,客户端在调用这个函数的时候,必须要知道这个函数的一些信息,这样就产生了耦合。为了解耦,我们采用命令模式,在客户端和具体的提供服务的对象之间添加了一层,也就是Invoker,它会负责将来自客户端的请求委托给具体的提供服务的对象,这样,客户端无需知道提供服务的具体事那个一个对象,而提供服务的对象也无需知道她所服务的对象是谁。这样讲还是有些抽象,我们来看一个实际的例子。
// Command.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include
通过命令模式,通过在客户端和具体的命令之间添加一层Invoker,剪断了客户端和具体服务提供者之间的耦合,降低了两者之间的耦合度,同时也增加了灵活性,比如我们可以灵活的某一个请求的服务提供者,通过单独的服务提供者Command类,可以很方便的提供redo和undo的功能等等,这些都是命令模式的优势。
我这样的解释可能还是难以理解,我们再来看一个现实中的Command模式的例子。例如,我们在饭店点菜吃饭就是一个很好的命令模式的例子。在这个场景中,有这样几个角色:
顾客:Client,也就是我们的客户端
服务员:Invoker,她负责处理来自客户端的请求并将其封装成命令Command
订单:Order,Command,这就是Invoker所封装的请求
厨师:Cook,receiver,这就是最终处理请求的服务提供者,很多时候,receiver和Command合并在了一起。
当顾客向服务员点菜,整个饭店所能够提供的服务,也即是能够做的菜都在菜单上,例如我们例子中的m_maoCommands(服务员Invoker当然是知道什么才可以有,什么菜不可以有的),顾客的请求都在菜单这个范围内,顾客将这些请求进行组合向服务员点菜,服务员将顾客的这个请求写到订单上,这样就封装成了一个个的命令Command,然后,厨师再执行这些命令,一道菜做好了,也就是完成了这个请求。
通过命令模式,我们可以很好的进行客户端和具体提供服务的对象之间的耦合,就像我们在饭店吃饭,从来没有见过厨师一样,也不用管厨师长得帅不衰,我们见到的只是服务员,只要服务员漂亮热情就行了,即使厨师换了我们都不用知道。