定義
將一個請求封裝成一個對象,從而讓用戶使用不同的請求把客戶端參數(shù)化;對請求排隊或者記錄請求日志酝润,以及支持可撤銷的操作。
使用場景
- 需要抽象出待執(zhí)行的動作璃弄,然后以參數(shù)的形式提供出來——類似于過程設(shè)計中的回調(diào)機制要销,而命令模式正是回調(diào)機制的一個面向?qū)ο蟮奶娲贰?/li>
- 在不同的時刻指定、排列和執(zhí)行請求夏块。一個命令對象可以有與初始請求無關(guān)的生存期疏咐。
- 需要支持取消操作
- 支持修改日志功能纤掸,這樣當系統(tǒng)崩潰時,這些修改可以被重做一遍浑塞。
- 需要支持實務(wù)操作
其實說了那么多借跪,簡單的說就是C是具體的操作,B封裝了C的操作酌壕,A控制了B去做事從而控制具體的操作C掏愁,用戶類Client控制A從而去控制C......
UML圖
命令模式.png
角色介紹
優(yōu)點
- 更弱的耦合性
- 更靈活的控制性
- 更好的擴展性
缺點
- 類膨脹(所有設(shè)計模式的通病)
大量衍生類的膨脹卵牍,這是一個不可避免的問題托猩。
例子
按照UML圖,接收者類執(zhí)行具體的邏輯
/**
* 接收者類辽慕,(類C)
* Created by Niwa on 2017/8/7.
*/
public class Receiver {
/**
* 真正執(zhí)行具體命令邏輯的方法
*/
public void action() {
System.out.println("執(zhí)行具體操作");
}
}
/**
* 抽象命令接口
* Created by Niwa on 2017/8/7.
*/
public interface Command {
/**
* 執(zhí)行具體命令邏輯的方法
*/
void execute();
}
ConcreteCommand用來操作接收者類
/** 具體的命令類(B類)京腥,用于操控Receiver類,B類可以具體成某一個動作(對象)
* Created by Niwa on 2017/8/7.
*/
public class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
//調(diào)用接收者的相關(guān)方法
receiver.action();
}
}
Invoker 用來操控ConcreteCommand類
** 請求者類(A類)
* Created by Niwa on 2017/8/7.
*/
public class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
/**
* 請求者類的開始活動方法溅蛉,用于調(diào)用B類來控制C
* */
public void startAction(){
//調(diào)用具體命令對象的相關(guān)方法公浪,執(zhí)行具體命令
command.execute();
}
}
Test類用來控制Invoker 類
/** 用戶類
* Created by Niwa on 2017/8/7.
*/
public class Test {
public static void main(String[] args){
//構(gòu)建接收者對象
Receiver receiver = new Receiver();
//根據(jù)接收者對象構(gòu)造一個命令對象()
//關(guān)鍵在這里,具體的命令可以有很多種船侧,比如每個命令類作為一個類欠气,大大降低偶耦合
Command command = new ConcreteCommand(receiver);
//根據(jù)具體的對象構(gòu)造請求者對象
Invoker invoker = new Invoker(command);
//執(zhí)行請求方法
invoker.startAction();
}
}
該例子的邏輯就是Test類控制Invoker類去控制Command類從而控制Receiver類
參考:
《Android源碼設(shè)計模式解析與實戰(zhàn)讀書》
各大佬博客
源代碼:DesignPattern
end