Java 設計模式 -- 命令模式

pbyp4943 8年前發布 | 6K 次閱讀 命令模式 Java Java開發

前提

介紹這么模式之前,我們首先來看看它的類圖。

根據這個圖我們來分析一下何為命令模式。首先就是我們的 Client 想要實現一個功能,于是它就創建了一個 Command , 為了方便調用將 Command 封裝在了 Invoker 中,當我們想調用的時候, Invoker 會執行內部 Command 提供的方法, Receiver 接收到 Command 的請求,為其提供底部支持。

多說無益,我將通過一個例子介紹命令模式。

實例

目前大部分的軟件都支持用戶自定義界面,比如說我們可以修改字體大小,背景顏色等。我們就以此為例。首先,寫出兩個類。

public class Font {
    private String fontSize = "normal";

public String getFontSize() {
    return fontSize;
}

public void setFontSize(String fontSize) {
    this.fontSize = fontSize;
}

} public class Background { private String bgColor = "white";

public String getBgColor() {
    return bgColor;
}

public void setBgColor(String bgColor) {
    this.bgColor = bgColor;
}

}</code></pre>

以上這兩個類在命令模式的類圖中扮演的是 Receiver 角色,提供底層支持。

public interface Command {
    public void execute();
}

這是 Command , 修改字體大小和背景的類都繼承于此。

public class NormalFontCommand implements Command {
    private Font font;

public NormalFontCommand(Font font) {
    this.font = font;
}

@Override
public void execute() {
    font.setFontSize("Normal");
}

} public class LargeFontCommand implements Command {

private Font font;

public LargeFontCommand(Font font) {
    this.font = font;
}

@Override
public void execute() {
    font.setFontSize("Large");
}

}</code></pre>

很簡單的,我們只是在類中獲得一個 Font 類的引用,然后調用 setFontSize() 方法對字體的大小進行設置。

因為背景顏色的種類特別多,如果我們針對每種顏色都編寫一個類,那就太不實際了。所以我們決定用兩個類去實現它,一個類表示是默認顏色,一個是類表示非默認顏色。

public class DefaultBackground implements Command {

private Background background;

public DefaultBackground(Background background) {
    this.background = background;
}

@Override
public void execute() {
    background.setBgColor("Default color");
}

}

public class CustomBackground implements Command { private Background background; private String color = null;

public CustomBackground(Background background) {
    this.background = background;
}

@Override
public void execute() {
    background.setBgColor("Custom background");
}

}</code></pre>

好了,通過以上操作,我們不僅定義好了 Command ,還定義了 Receiver 類,下面就差 Invoker 類了。

public class Invoker {

private ArrayList<Command> commands;

public Invoker() {
    commands = new ArrayList<>();
}

public void setCommand(int i, Command command) {
    commands.add(i, command);
}

public void update(int i) {
    commands.get(i).execute();
}

}</code></pre>

用 ArrayList 存儲 Command 命令,不過我們需要指定序號,方便以后我們使用。

下面開始進行測試

public class Client {

public static void main(String[] args) {

    Font font = new Font();
    Background background = new Background();

    NormalFontCommand normalFontCommand = new NormalFontCommand(font);
    LargeFontCommand largeFontCommand = new LargeFontCommand(font);
    DefaultBackground defaultBackground = new DefaultBackground(background);
    CustomBackground customBackground = new CustomBackground(background);

    Invoker invoker = new Invoker();
    invoker.setCommand(0, normalFontCommand);
    invoker.setCommand(1, largeFontCommand);
    invoker.setCommand(2, defaultBackground);
    invoker.setCommand(3, customBackground);

    invoker.update(3);

    System.out.println(background.getBgColor());
}

}</code></pre>

我們首先把所有的命令添加到了 Invoker , 然后直接調用 update() 方法就可以了。

這么做有什么好處呢?看的出來,可以將很多命令放進 Invoker , 它并不知道功能是如何實現的,它就像一個中介, Client 請求一個功能,它就將這個請求轉給 Command 去實現。這種模式有很多的用途,比如說多功能遙控器,日志打印等。

還有一點不得不說的,我們可以使用宏命令,什么是宏命令呢?就是寫一個 Command ,這個 Command 可以實現多個功能。比如說我們可以同時修改背景和

來自:http://www.jianshu.com/p/3fd3166c7662

 

 本文由用戶 pbyp4943 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!