Java行爲型設計模式 —— 命令模式打響戰爭的開始

一、引言

陽光明媚的一個週末。

上一章講了模板方法設計模式,今天小編繼續來說命令設計模式,也是行爲型設計模式的一種~~~~

二、命令模式基本介紹

所謂命令模式,就是下達命令,最後有人執行命令。

大家想想古代打戰的時候,將軍下達命說,明天需要攻下某某某山頭。

那麼將軍就找來了參謀長,這個時候參謀長得知了將軍的意思,參謀長就找來每個軍營的負責人,說一營、二營全部人員明天出發某某某山頭。

你看將軍其實他並不知道是哪個具體營的士兵大戰,中間通過了這個參謀長來給軍營的人溝通。

命令模式(Command Pattern)思想也是如此,我們經常需要向某些對象發送請求,但是不知道到請求的接收者是誰。在命令模式中,會將一個請求或者說一個命令封裝成爲一個對象,我們只需要在程序運行時指定具體的請求接收者即可。更加通俗的來說,將軍發佈命令,參謀長得知命令通知士兵,士兵具體執行該命令,由此可見,命令模式使得請求的發送者(將軍)與請求的接收者(士兵)消除彼此之間的耦合度,讓對象之間的調用更加靈活,實現解耦。

三、命令模式案例演示

吶吶吶吶吶吶麼,就以剛剛舉例打戰的案例來使用具體代碼實現。

打戰就肯定要有士兵,所以我們先來創建一個士兵的類,並且定義士兵所能做的事。士兵也是最後命令的執行者

/**
 * @Auther: IT賤男
 * @Date: 2019/12/13 10:40
 * @Description: 定義士兵動作,命令執行者
 */
public class Robot {

    private String name;

    public Robot(String name) {
        this.name = name;
    }

    /**
     * 士兵開火
     */
    public void fire() {
        System.out.println(this.name + "正在開火......");
    }

    /**
     * 士兵停火
     */
    public void stop() {
        System.out.println(this.name + "停止開火......");
    }
}

定義抽象的命令,可以定義命令的行爲,比如執行命令,撤銷命令。 有抽象的命令,那麼當然就肯定有具體執行命令對象。文章上面有說,會將一個請求或者說一個命令封裝成爲一個對象,那麼既一個命令就是一個對象。接下來我們還要創建開火和停止開火的兩個命令對象。

/**
 * @Auther: IT賤男
 * @Date: 2019/12/12 13:58
 * @Description: 抽象命令者
 */
public interface Command {

    /**
     * 執行命令
     */
    void execute();

}
/**
 * @Auther: IT賤男
 * @Date: 2019/12/13 10:44
 * @Description: 開火命令,將命令請求封裝成對象
 */
public class RobotFireCommand implements Command {

    // 聚合士兵,士兵是具體執行者
    private Robot robot;

    public RobotFireCommand(Robot robot) {
        this.robot = robot;
    }

    @Override
    public void execute() {
        // 調用士兵的開火方法
        robot.fire();
    }
}
/**
 * @Auther: IT賤男
 * @Date: 2019/12/13 10:47
 * @Description: 停止開火命令,將命令請求封裝成對象
 */
public class RobotStopCommand implements Command {

    private Robot robot;

    public RobotStopCommand(Robot robot) {
        this.robot = robot;
    }

    @Override
    public void execute() {
        robot.stop();
    }
}

士兵和命令都有了,那麼這個時候常參謀長就該登場了,參謀長就可以接收命令,以及通知執行命令。

/**
 * @Auther: IT賤男
 * @Date: 2019/12/13 10:48
 * @Description: 參謀長的角色 負責接受命令,以及通知士兵執行
 */
public class Staff {

    // 命令集合
    private List<Command> commandList = new ArrayList<>();

    // 添加命令
    public void addCommand(Command command) {
        commandList.add(command);
    }

    // 執行命令
    public void excuteCommands() {
        for (Command command : commandList) {
            command.execute();
        }
        commandList.clear();
    }

}
/**
 * @Auther: IT賤男
 * @Date: 2019/12/13 10:59
 * @Description:
 */
public class Client {

    public static void main(String[] args) {
        // 創建一個士兵
        Robot robot = new Robot("張三");
        RobotFireCommand fireCommand = new RobotFireCommand(robot);

        // 這個時候參謀長得知了將軍的消息,要開火了
        Staff staff = new Staff();
        staff.addCommand(fireCommand);
        // 下達命令給士兵
        staff.excuteCommands();

        // 這個時候敵人消滅了,下命令停止開火
        RobotStopCommand stopCommand = new RobotStopCommand(robot);
        staff.addCommand(stopCommand);
        // 下達命令給士兵
        staff.excuteCommands();


    }

}

四、命令模式使用注意細節

命令模式最主要的作用就是把請求的調用者和請求執行者進行解耦,每一個具體命令就是單獨的一個對象,缺點也就很顯而易見了,如果有很多命令就會導致類爆炸的問題。

其實一個嚴謹的命令模式,往往還需要支持撤銷的功能,本章小編就沒有演示了,因爲單單在命令模式中使用撤銷,小編感覺稍微有點點的雞肋。 命令模式可以和備忘錄模式進行組合使用,這樣備忘錄可以記錄上一次的操作,命令模式就可以撤銷上一次的操作了。

總的來說,命令模式還是比較好理解的。

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