将请求封装为一个对象。
1.解耦。
将Invoker和receiver分离。即:“decouple the ogject that invokes the operation from the one having the knowledge to perform it”。由于invoker和receiver的分离,他们可以各自变化。比如:command的一个典型的例子就是GUI程序,可以在不改变程序逻辑的情况下,可以插入(跟换)新的gui元素,即换肤的功能;同样可以在不改变用户界面的条件下改变程序逻辑。
解耦是软件开发中的一个很重要的部分。各部分之间的耦合度要尽量降到最低。设计gui元素的时候,用户对gui元素进行了某种操作,则需要执行相应的处理。比如,用户按下按钮,需要执行一段程序,但是,在设计gui的时候,根本不知道用户按下按钮的时候要执行什么操作,这些需要由应用程序开发者来决定。于是gui的设计者需要一种机制来让应用程序开发者来指定(如按下按钮)对应的操作。于是command起的作用是将用户的动作从窗口传送至应用程序逻辑上。在面向过程的语言中,这种机制由回调函数来实现。在oo的语言中,我们可以使用command模式。
很多情况下,我觉得解耦就是增加一层间接性(增加一个中间层)。这里command就好像一个中间层。本来可以写段代码直接对应“用户按下按钮”这个动作,但是中间夹一个command,“用户按下按钮”的时候,只知道有个command,只知道command有个execute函数,只知道简单的调用以下command的execute函数。execute函数到底要干什么,它一无所知。
2.可以动态replace command
同一个菜单选项,可能在不同的contex下对应不同的操作。比如实现与上下文有关的菜单选项。在不同的上下文中,设置不同的command对象,以执行不同的操作。这种情况又和state模式以及strategy模式很相似。
3.command可以传递,保存
可以生成一个command并进行保存、传递、排队等操作。可以过一段时间再执行此command。可以讲command序列化,当系统crash的时候,可以读取以前所执行过的commands,并重新执行一遍,从而恢复到系统crash以前的状态。在这中情况下,command更像一个“事务”,事实上,command模式的一个别名就是transaction(事务)。
4.支持undo,redo
可以为command增加几个函数,如undo(),用来撤销上一次操作。这里会涉及到prototype以及memento模式。
5.可以将多个command组和
这种情况和composite模式有联系。
6.容易增加新的command而不影响已有系统
其实这一点只是第一条的一个方面:“由于invoker和receiver的分离,他们可以各自变化”