Command Pattern(命令模式)
定义:
将一个请求封装成一个对象,因此可以参数化多个客户的不同请求,将请求排队,记录请求日志,并且支持撤销操作。(来自:《深入浅出设计模式》莫勇腾)
应用情景:
- 当你需要与动作有关的对象来作为参数。
- 你需要在不同的时间创建请求,生成请求队列,执行请求。
- 你需要支持取消、保存修改日志或处理事务(事务包括大量修改的数据)功能。
- 你需要支持宏命令。
前奏
我举个例子,假设天暗下来了,那么通常情况下,我们要开电灯,日光灯,台灯等,假设一盏灯对应一个开关,总共开5盏灯,那么我们要按五个开关,通常情况下,如果灯一多起来,那么人就会感觉很费劲,设计程序时,我们这样设计,人作为一个打开开关的类,每一盏灯作为一个类,那么通常我们会new 五个灯的类,然后用一个方法turnLightOn()来打开所有的灯,
如下
事实上,如果我们再增加一盏灯的话,Person类必须修改,方法也得修改,而且也会使得Person类越来越庞大,而设计模式的思想告诉我们必须保护起变化来,我们引入一个中间类,Command,把所有的命令放入到里边,如下列UML图:
package lights.lights;
/***********************************************************************
* Module: Person.java
* Author: hongqin
* Purpose: Defines the Class Person
***********************************************************************/
import java.util.*;
/** @pdOid e48e5f4c-fa8c-4d2f-95e9-5739f160120a */
public class Person {
public List<Command> commandList;
public Person() {
commandList = new ArrayList<Command>();
}
public int turnLightOn() {
Command[] commands = (Command[])commandList.toArray();
for (Command command : commands) {
command.execute();
}
return 0;
}
/** @pdGenerated default add
* @param newCommand */
public void addCommand(Command newCommand) {
if (!this.commandList.contains(newCommand))
this.commandList.add(newCommand);
}
/** @pdGenerated default remove
* @param oldCommand */
public void removeCommand(Command oldCommand) {
if (oldCommand == null)
return;
if (this.commandList != null)
if (this.commandList.contains(oldCommand))
this.commandList.remove(oldCommand);
}
}
实例:
注:司机不必关注加速的细节,只需要发出一个命令即可实现加减速。命令可以是连续的(队列操作),重复的,可撤销的操作。
注:
- 定义以及应用场景来自《深入浅出设计模式》莫勇腾
- UML软件:PowerDesigner12.5