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