1.意圖
將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而使你可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化,對(duì)請(qǐng)求排隊(duì)或記錄請(qǐng)求日志,以及支持可撤銷的操作。
2.結(jié)構(gòu)

Command接口提供了Execute方法,客戶端通過Invoker調(diào)用命令操作來調(diào)用Recriver,繞了一大圈,但是卻把具體對(duì)Receiver的操作請(qǐng)求封裝在具體的命令中,是客戶端對(duì)recriver的操作清晰簡明。
但是在實(shí)際項(xiàng)目中,我們常常忽略Receiver,而把命令對(duì)象的目標(biāo)對(duì)象直接設(shè)置為子類自己的成員變量或者作為execute()方法的臨時(shí)變量。
以Android中的Runnable(在java.lang包下)為例,我們畫出UML結(jié)構(gòu)圖如下:

想不到我們天天寫的代碼無意識(shí)中就是用到了命令模式,所謂模式,就是無所不在。
3.代碼
命令接口Runnable定義如下:
public interface Runnable {
public abstract void run();
}
調(diào)用者Thread簡化版代碼:
//命令模式這里不需要繼承Runnable接口,但是這里考慮到實(shí)際情況,比如方便性等,繼承了Runnable接口,實(shí)現(xiàn)了run方法,這個(gè)是Thread自身的運(yùn)行run的方法
class Thread implements Runnable {
private Runnable target;
public Thread(Runnable target) {
this.target = target;
}
public synchronized void start() {
if (threadStatus != 0 || this != me)
throw new IllegalThreadStateException();
group.add(this);
start0();//這個(gè)是本地方法,調(diào)用run方法
if (stopBeforeStart) {
stop0(throwableFromStop);
}
}
//可選
public void run() {
if (target != null) {
target.run();
}
}
}
客戶端只需要new Thread(new Runnable(){}).start()就開始執(zhí)行相關(guān)的一系列的請(qǐng)求,這些請(qǐng)求大部分都是實(shí)現(xiàn)Runnable接口的匿名類。
4.效果
(1).行為型模式;
(2).將調(diào)用對(duì)象的操作和知道如何實(shí)現(xiàn)該操作的對(duì)象解耦;
(3).多個(gè)命令可以裝配成一個(gè)復(fù)合命令;
(4).增加新的命令很容易。