- 幾分鐘帶你搞懂策略模式
- 幾分鐘帶你搞懂觀察者模式
- 一文徹底搞明白工廠和抽象工廠
- 一文搞明白裝飾者模式
- 最全單例模式
- 幾段代碼搞明白命令模式
關於命令模式的定義,我就直接引用Head First了:命令模式將“請求”封裝成對象,以便使用不同的請求。目的是將發起請求的對象和具體執行處理請求的對象完全解耦,並能靈活擴展具有不同操作的接收者對象。
命令模式
假如我們有一個遙控器可以控制不同硬件設備。如:通過一個按鈕來控制智能燈的“開燈”,“關燈”。
這是智能燈的接口。當前只有兩個方法,即開燈和關燈操作。
public class Light {
public void on() {
System.out.println("開燈");
}
public void off() {
System.out.println("關燈");
}
}
這是命令對象接口。通過調用命令對象的 execute() 方法,即可執行具體的接收者操作。
public interface Command {
public void execute();
}
這是智能燈命令對象,是 Command 的實現類。我們將開燈的請求進行了封裝,這個請求即調用“接收者開燈”這個操作。
public class LightOnCommand implements Command {
private Light mLight;
public LightOnCommand(Light light) {
mLight = light;
}
@Override public void execute() {
mLight.on();
}
}
同樣我們將“接收者關燈”這個請求,也封裝成對象。
public class LightOffCommand implements Command {
private Light mLight;
public LightOnCommand(Light light) {
mLight = light;
}
@Override public void execute() {
mLight.off();
}
}
假如我們有一個遙控器類,可以通過按鈕控制智能燈的“開燈”和“閉燈”,代碼見下:
public class Control {
private Command mComBtn;
public void setCommand(Command comBtn) {
mComBtn = comBtn;
}
public void btnWasPressed() {
mComBtn.execute();
}
}
發出請求的對象(Control 類)與接收者(Light)是完全解耦的,兩者是通過命令對象(Command實現類)溝通的,命令對象封裝了接收者的一組動作,當然可多組,這裏即“打開智能燈”,“關閉智能燈”的操作。調用者 Control 可直接通過 execute 方法,可動態指定執行特定接收者命令。 我們來進行下測試:
public class Test {
public static void main(String[] ags) {
Control control = new Control();
Light light = new Light();
// 開燈
control.setCommand(new LightOnCommand(light));
control.execute();
// 關燈
control.setCommand(new LightOffCommand(light));
control.execute();
}
}
也許你會有疑惑,爲何不實現一個智能硬件接口 Ihardware呢?讓我們的Control 直接持有Ihardware呢,針對上面這個類當然可以的。但是如果我們需要再擴展一個智能空調類 AirCon,甚至更多硬件類呢?
public class AirCon {
public void on();
public void off();
// 獨有的調節溫度
public void adjustTemperature();
}
這個時候再想想命令模式,是不是更有優勢呢?我們只需要將調節溫度這個請求封裝成對象,而完全不必更改 Control 對象。當然這也會和裝飾者模式一樣,會造成大量的小類,所以具體的選型需要全方位衡量判斷。