一、引言
陽光明媚的一個週末。
上一章講了模板方法設計模式,今天小編繼續來說命令設計模式,也是行爲型設計模式的一種~~~~
二、命令模式基本介紹
所謂命令模式,就是下達命令,最後有人執行命令。
大家想想古代打戰的時候,將軍下達命說,明天需要攻下某某某山頭。
那麼將軍就找來了參謀長,這個時候參謀長得知了將軍的意思,參謀長就找來每個軍營的負責人,說一營、二營全部人員明天出發某某某山頭。
你看將軍其實他並不知道是哪個具體營的士兵大戰,中間通過了這個參謀長來給軍營的人溝通。
命令模式(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();
}
}
四、命令模式使用注意細節
命令模式最主要的作用就是把請求的調用者和請求執行者進行解耦,每一個具體命令就是單獨的一個對象,缺點也就很顯而易見了,如果有很多命令就會導致類爆炸的問題。
其實一個嚴謹的命令模式,往往還需要支持撤銷的功能,本章小編就沒有演示了,因爲單單在命令模式中使用撤銷,小編感覺稍微有點點的雞肋。 命令模式可以和備忘錄模式進行組合使用,這樣備忘錄可以記錄上一次的操作,命令模式就可以撤銷上一次的操作了。
總的來說,命令模式還是比較好理解的。