定義:
將一個請求封裝為一個對象,從而使我們可用不同的請求對客戶進行參數化。
本質上是對命令進行封裝,將發出命令的責任和執行命令的責任分隔開。
角色:
- 接收者類:實現了具體的業務操作,拿電視機來說,這個類實現了電視機的開啟和關閉的真實操作方法。
- 抽象命令類:定義了一個執行命令的方法接口,由其子類實現。
- 具體命令類(一個命令一個類):實現抽象命令接口,關聯接收者類,調用接受者類中具體的一個命令,比如這個具體命令類是要開啟電視機,那么執行命令的方法就調用接受者對象中的開啟命令。
- 調用者類:相當於遙控器,把所有可能的操作集合在一起,客戶端只需要使用遙控器就可以完成所有命令的發起,構造方法(形參是是抽象命令隊對象,實參是具體命令對象)完成所有具體命令對象的注入,提供執行命令的方法,用具體命令對象調用具體命令的執行方法。
關鍵代碼:
//接收者:真正執行命令的對象
public class Light {
public void open(){
System.out.println("打開電燈!");
}
}
public interface Command {
public void execute();
}
// 這是一個命令,所以需要實現Command接口
public class LightOnCommand implements Command {
Light light;
// 構造器傳入某個電燈,以便讓這個命令控制,然后記錄在實例變量中
public LightOnCommand(Light light) {
this.light = light;
}
// 這個execute方法調用接收對象的on方法
public void execute() {
light.on();
}
}
public class SimpleRemoteControl {
// 有一個插槽持有命令,而這個命令控制着一個裝置
Command slot;
public SimpleRemoteControl() {}
// 這個方法用來設置插槽控制的命令
public void setCommand(Command command) {
slot = command;
}
// 當按下按鈕時,這個方法就會被調用,使得當前命令銜接插槽,並調用它的execute方法
public void buttonWasPressed() {
slot.execute();
}
}
客戶端使用
public class RemoteControlTest {
public static void main(String[] args) {
// 遙控器就是調用者,會傳入一個命令對象,可以用來發出請求
SimpleRemoteControl remote = new SimpleRemoteControl();
// 現在創建一個電燈對象,此對象也就是請求的接收者
Light light = new Light();
// 這里創建一個命令,然后將接收者傳給它
LightOnCommand lightOn = new LightOnCommand(light);
// 把命令傳給調用者
remote.setCommand(lightOn);
// 模擬按下按鈕
remote.buttonWasPressed();
}
}
核心理解
命令模式主要完成的事情是把命令的具體實施和命令的發出解耦。
有一個具體干活的類(命令接收者類),這個類里有所有執行具體命令的方法。
有一個抽象的命令類,這個類定義了一個執行的方法接口,然后它的子類(這些子類的個數和具體命令的個數是一致的,比如說那個具體干活的類需要做兩件事,一個是打開電腦,一個是關閉電腦,那么就會有兩個不同的子類來繼承這個抽象的命令類!)繼承這個類並重寫它的執行命令的方法,這里有個點需要注意:這些子類需要關聯那個命令接收者類,用那個類的方法來重寫執行方法!
