一、命令模式介紹
命令模式:將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化,對請求排隊或記錄請求日志。以及支持可撤銷的操作。
說白了,就是將一系列的請求命令封裝起來,不直接調用真正執行者的方法,這樣比較好擴展。
命令模式UML圖:
Command(抽象命令類):抽象出命令對象,可以根據不同的命令類型。寫出不同的實現類
ConcreteCommand(具體命令類):實現了抽象命令對象的具體實現
Invoker(調用者/請求者):請求的發送者,它通過命令對象來執行請求。一個調用者並不需要在設計時確定其接收者,因此它只與抽象命令來之間
存在關聯。在程序運行時,將調用命令對象的execute() ,間接調用接收者的相關操作。
Receiver(接收者):接收者執行與請求相關的操作,真正執行命令的對象。具體實現對請求的業務處理。未抽象前,實際執行操作內容的對象。
Client(客戶端):在客戶類中需要創建調用者對象,具體命令類對象,在創建具體命令對象時指定對應的接收者。發送者和接收者之間沒有之間關系。
都通過命令對象來調用。
二、命令模式代碼實現
首先定義一個命令的接收者,也就是到最后真正執行命令的那個人
1
2
3
4
5
6
|
//接收者:真正執行命令的對象
public
class
Receiver {
public
void
action(){
System.out.println(
"命令執行了......."
);
}
}
|
然后定義抽象命令和抽象命令的具體實現,具體命令類中需要持有真正執行命令的那個對象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
//抽象命令類:抽象的命令,可以根據不同類型的命令寫出不同的實現
public
interface
Command {
//調用命令
void
execute();
}
//具體命令類
class
ConcreteCommand
implements
Command{
private
Receiver receiver;
//持有真正執行命令對象的引用
public
ConcreteCommand(Receiver receiver) {
super
();
this
.receiver = receiver;
}
@Override
public
void
execute() {
//調用接收者執行命令的方法
receiver.action();
}
}
|
接下來就可以定義命令的發起者了,發起者需要持有一個命令對象。以便來發起命令。
1
2
3
4
5
6
7
8
9
10
11
12
|
//請求者/調用者:發起執行命令請求的對象
public
class
Invoker {
private
Command command;
//持有命令對象的引用
public
Invoker(Command command) {
super
();
this
.command = command;
}
public
void
call(){
//請求者調用命令對象執行命令的那個execute方法
command.execute();
}
}
|
客戶端測試:客戶端
1
2
3
4
5
6
|
public
static
void
main(String[] args) {
//通過請求者(invoker)調用命令對象(command),命令對象中調用了命令具體執行者(Receiver)
Command command =
new
ConcreteCommand(
new
Receiver());
Invoker invoker =
new
Invoker(command);
invoker.call();
}
|
結果打印:命令執行了.......
代碼的UML圖如下:
三、應用場景
Struts2中action中的調用過程中存在命令模式
數據庫中的事務機制的底層實現
命令的撤銷和恢復:增加相應的撤銷和恢復命令的方法(比如數據庫中的事務回滾)
參考資料:
大話設計模式(帶目錄完整版).pdf
HEAD_FIRST設計模式(中文版).pdf
尚學堂_高淇_java300集最全視頻教程_【GOF23設計模式】