定義:
將一個請求封裝成對象,使得請求發送者和請求接受者之間相互隔離,消除兩者之間的耦合。引入命令類,使得不同請求對客戶參數化,並且可以對命令添加附件操作,如:排隊、撤銷、日志、組合等。
結構圖:
- Command:抽象命令類,一般是一個抽象類或者接口。在其中定義了命令的執行execute()、undo()等操作。
- ConcreteCommand:具體命令類,實現了抽象命令類的方法,並且持有命令接受者的引用。具體執行方法時,調用接受者的相關操作。
- Invoker:請求發送者,通過命令對象執行請求。針對抽象命令類編程,並不需要關心對應的命令如何執行,被誰執行。與抽象命令的關聯關系也不固定,可以通過注入或者構造的方法或者采用XML和反射的方法來進行關聯。
- Reciver:請求接受者,執行請求的相關操作,對請求進行詳細的業務處理。
命令隊列
當一個請求需要將需要多個接受者進行處理的時候,可以將多個命令放入隊列中,每個命令對應一個接受者。請求發送者執行請求時,將遍歷請求隊列,對每個命令執行操作。
class CommandQueue {
//定義一個ArrayList來存儲命令隊列
private ArrayList<Command> commands = new ArrayList<Command>();
public void addCommand(Command command) {
commands.add(command);
}
public void removeCommand(Command command) {
commands.remove(command);
}
//循環調用每一個命令對象的execute()方法
public void execute() {
for (Object command : commands) {
((Command)command).execute();
}
}
}
class Invoker {
private CommandQueue commandQueue; //維持一個CommandQueue對象的引用
//構造注入
public Invoker(CommandQueue commandQueue) {
this. commandQueue = commandQueue;
}
//設值注入
public void setCommandQueue(CommandQueue commandQueue) {
this.commandQueue = commandQueue;
}
//調用CommandQueue類的execute()方法
public void call() {
commandQueue.execute();
}
}
命令的撤銷
在抽象命令中不僅定義excute()接口,也定義undo()接口。所有具體執行的命令需要實現undo操作,可以結合備忘錄模式來記錄歷史狀態,完成該撤銷操作。
//抽象命令類
abstract class AbstractCommand {
public abstract int execute(); //聲明命令執行方法execute()
public abstract int undo(); //聲明撤銷方法undo()
}
宏命令
宏命令又稱作組合命令,可以看做命令模式與組合模式的聯合。對於宏命令可以擁有一個命令集合,當具體執行的時候需要遍歷集合中的所有命令來遞歸地執行操作。
優點:
- 將請求發送者和接受者之間完全解耦,使兩者都具有很好的獨立性。相同的請求者可以對應不同的接受者,而相同的接受者可以供不同請求者使用。
- 可以很方便地添加新的命令,無需修改源碼,可以通過配置文件制定。
- 可以對命令添加很對其它的附加操作,例如:隊列、日志、宏命令等,更好地符合業務需求。
實例: