設計模式(六)幾段代碼搞明白命令模式

關於命令模式的定義,我就直接引用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 對象。當然這也會和裝飾者模式一樣,會造成大量的小類,所以具體的選型需要全方位衡量判斷。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章