第十五章:命令模式
一、基本介绍
1)命令模式有三个组成部分:命令发起者(Invoker)、命令(Command)、命令接收者(Receiver)
2)消除了命令发起者和接收者之间的耦合
3)命令模式还支持撤销的操作
基本类图:
二、模式实例
实现指挥官可以向士兵发送命令,指挥行动的功能
Command 抽象类
public abstract class Command {
abstract public void execute();
abstract public void undo();
}
命令接收者类
Archer
public class Archer {
public void fireAtWill() {
System.out.println("弓箭手:正在自由射击");
}
public void stopFire() {
System.out.println("弓箭手:停止射击中");
}
}
Cavalry
public class Cavalry {
public void charge() {
System.out.println("骑兵:To Death!!!");
}
public void fallback() {
System.out.println("骑兵:正在远离战场");
}
}
具体命令类
ArcherFireCommand
public class ArcherFireCommand extends Command {
private Archer archer;
public ArcherFireCommand(Archer archer) {
this.archer = archer;
}
public void setArcher(Archer archer) {
this.archer = archer;
}
@Override
public void execute() {
System.out.println("指挥官:自由射击");
archer.fireAtWill();
}
@Override
public void undo() {
System.out.println("指挥官:撤销命令");
archer.stopFire();
}
}
ArcherStopCommand
public class ArcherStopCommand extends Command {
private Archer archer;
public ArcherStopCommand(Archer archer) {
this.archer = archer;
}
public void setArcher(Archer archer) {
this.archer = archer;
}
@Override
public void execute() {
System.out.println("指挥官:停止射击");
archer.stopFire();
}
@Override
public void undo() {
System.out.println("指挥官:撤销命令");
archer.fireAtWill();
}
}
CavalryBackCommand
public class CavalryBackCommand extends Command {
private Cavalry cavalry;
public CavalryBackCommand(Cavalry cavalry) {
this.cavalry = cavalry;
}
public void setCavalry(Cavalry cavalry) {
this.cavalry = cavalry;
}
@Override
public void execute() {
System.out.println("指挥官:骑兵撤离战场");
cavalry.fallback();
}
@Override
public void undo() {
System.out.println("指挥官:撤销命令");
cavalry.charge();
}
}
CavalryChargeCommand
public class CavalryChargeCommand extends Command{
private Cavalry cavalry;
public CavalryChargeCommand(Cavalry cavalry) {
this.cavalry = cavalry;
}
public void setCavalry(Cavalry cavalry) {
this.cavalry = cavalry;
}
@Override
public void execute() {
System.out.println("指挥官:骑兵冲锋!");
cavalry.charge();
}
@Override
public void undo() {
System.out.println("指挥官:撤销命令");
cavalry.fallback();
}
}
空命令类
public class BlankCommand extends Command {
@Override
public void execute() {
}
@Override
public void undo() {
}
}
命名发出者类
public class Commander {
private Map<String, Command> commands;
private Command preCommand;
private Command blankCommand;
public Commander() {
this.commands = new HashMap<>(8);
this.blankCommand = new BlankCommand();
}
public void addCommand(String id, Command command) {
commands.put(id, command);
}
public void releaseCommand(String id) {
Command command = commands.get(id);
if (command == null) {
command = this.blankCommand;
}
command.execute();
this.preCommand = command;
}
public void recallCommand() {
this.preCommand.undo();
}
}
测试类
public class CommandTest {
public static void main(String[] args) {
Commander commander = new Commander();
Archer archer = new Archer();
ArcherFireCommand archerFireCommand = new ArcherFireCommand(archer);
ArcherStopCommand archerStopCommand = new ArcherStopCommand(archer);
commander.addCommand("F2F3", archerFireCommand);
commander.addCommand("F2F1", archerStopCommand);
Cavalry cavalry = new Cavalry();
CavalryChargeCommand cavalryChargeCommand = new CavalryChargeCommand(cavalry);
CavalryBackCommand cavalryBackCommand = new CavalryBackCommand(cavalry);
commander.addCommand("F1F3", cavalryChargeCommand);
commander.addCommand("F1F5", cavalryBackCommand);
commander.releaseCommand("F2F3");
commander.recallCommand();
commander.releaseCommand("F1F3");
commander.recallCommand();
}
}
/********** result **********
指挥官:自由射击
弓箭手:正在自由射击
指挥官:撤销命令
弓箭手:停止射击中
指挥官:骑兵冲锋!
骑兵:To Death!!!
指挥官:撤销命令
骑兵:正在远离战场
*********** result **********/
三、优缺点
优点:
- 命令对象将 Invoker 和 Receiver 解耦
- 容易设计一个命令队列,只要将命令放入队列就可以多线程执行命令
- 容易实现对命令的撤销和重做
缺点:
- 导致过多具体的命令类
命令发出者的命令容器里可以预存空命令,这样就没必要每次判空