Java设计模式--命令模式

命令模式(别名:动作,事物)

为系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

Command Pattern(Another name:Action,Transaction)

Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

类图

模式的结构与使用

命令模式的结构中包四种角色。

  • 接受者(Receiver):接受者是一个类的实例,该实例负责执行与请求相关的操作。
  • 命令(Command):命令是一个接口,规定了用来封装“请求”的若干个方法,比如:execute()、undo()等方法。
  • 具体命令(Concrete command):具体命令是实现命令接口的类的实例。具体命令必须实现接口中的方法,比如execute(),使该方法封装一个“请求”。
  • 请求者(Invoker):请求者是一个包含Command接口变量的类的实例。请求者中的Command接口的变量可以存放任何具体命令的引用。请求者负责调用具体命令,让具体命令执行那些封装“请求”的方法,比如execute()方法。

简单的例子

接受者Receiver的类CompanyArmy.java

1
2
3
4
5
6
7
package Command;
public class CompanyArmy {
public void sneakAttack() {
System.out.println("我们知道了如何偷袭敌人,保证完成任务");
}
}

Command接口Command.java

1
2
3
4
5
package Command;
public interface Command {
public abstract void execute();
}

ConcreteCommand的实现类ConcreteCommand.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package Command;
public class ConcreteCommand implements Command {
CompanyArmy army;
public ConcreteCommand(CompanyArmy army) {
this.army = army;
}
@Override
public void execute() {
army.sneakAttack();
}
}

请求者类ArmySuperior.java

1
2
3
4
5
6
7
8
9
10
11
package Command;
public class ArmySuperior {
Command command;
public void setCommand(Command command) {
this.command = command;
}
public void startExecuteCommand() {
command.execute();
}
}

测试类Application.java

1
2
3
4
5
6
7
8
9
10
11
12
package Command;
public class Application {
public static void main(String[] args) {
CompanyArmy 三连 = new CompanyArmy();
Command command = new ConcreteCommand(三连);
ArmySuperior 指挥官 = new ArmySuperior();
指挥官.setCommand(command);
指挥官.startExecuteCommand();
}
}

运行截图

命令撤销的例子

接受者Receiver的类MakeDir.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package UndoCommand;
import java.io.File;
public class MakeDir {
public void createDir(String name) {
File dir = new File(name);
dir.mkdir();
}
public void deleteDir(String name) {
File dir = new File(name);
dir.delete();
}
}

Command接口Command.java

1
2
3
4
5
6
package UndoCommand;
public interface Command {
public abstract void execute(String name);
public abstract void undo();
}

ConcreteCommand的实现类ConcreteCommand.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package UndoCommand;
import java.util.ArrayList;
public class ConcreteCommand implements Command {
ArrayList<String> dirNameList;
MakeDir makeDir;
public ConcreteCommand(MakeDir makeDir) {
dirNameList = new ArrayList<String>();
this.makeDir = makeDir;
}
@Override
public void execute(String name) {
makeDir.createDir(name);
dirNameList.add(name);
}
@Override
public void undo() {
if (dirNameList.size() > 0) {
int m = dirNameList.size();
String str = dirNameList.get(m - 1);
makeDir.deleteDir(str);
dirNameList.remove(m - 1);
} else
System.out.println("没有需要撤销的操作");
}
}

请求者类RequestMakedir.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package UndoCommand;
public class RequestMakedir {
Command command;
public void setCommand(Command command) {
this.command = command;
}
public void startExecuteCommand(String name) {
command.execute(name);
}
public void undoCommand() {
command.undo();
}
}

测试类Application.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package UndoCommand;
public class Application {
public static void main(String[] args) {
MakeDir makeDir = new MakeDir();
Command command = new ConcreteCommand(makeDir);
RequestMakedir requestMakedir = new RequestMakedir();
requestMakedir.setCommand(command);
requestMakedir.startExecuteCommand("yxx");
requestMakedir.startExecuteCommand("yn");
requestMakedir.undoCommand();
}
}

运行截图

命令模式的优点

  • 在命令模式中,请求者(Invoker)不直接与接受者(Receiver)交互,即请求者(Invoker)不包含接受者(Receiver)的引用,因此彻底消除了彼此之间的耦合。
  • 命令模式满足“开-闭原则”。如果增加新的具体命令和该命令的接受者,不必修改调用者的代码,调用者就可以使用新的命令对象;反之,如果增加新的调用者,不必修改现有的具体命令和接受者,新增加的调用者就可以使用已有的具体命令。
  • 由于请求者的请求被封装到了具体命令中,那么就可以将具体命令保存到持久化的媒介中,在需要的时候,重新执行这个具体命令。因此,使用命令模式可以记录日志。
  • 使用命令模式可以对请求者的“请求”进行排队。每个请求都各自对应一个具体命令,因此可以按一定顺序执行这些命令。

适用命令模式的情景

  • 程序需要在不同的时刻制定、排列和执行请求。
  • 程序需要提供撤销操作。
  • 程序需要支持宏操作。

下载源码请到

MyGitHub

文章目录
  1. 1. 命令模式(别名:动作,事物)
  2. 2. Command Pattern(Another name:Action,Transaction)
  3. 3. 类图
  4. 4. 模式的结构与使用
  5. 5. 简单的例子
    1. 5.1. 接受者Receiver的类CompanyArmy.java
    2. 5.2. Command接口Command.java
    3. 5.3. ConcreteCommand的实现类ConcreteCommand.java
    4. 5.4. 请求者类ArmySuperior.java
    5. 5.5. 测试类Application.java
  6. 6. 运行截图
  7. 7. 命令撤销的例子
    1. 7.1. 接受者Receiver的类MakeDir.java
    2. 7.2. Command接口Command.java
    3. 7.3. ConcreteCommand的实现类ConcreteCommand.java
    4. 7.4. 请求者类RequestMakedir.java
    5. 7.5. 测试类Application.java
  8. 8. 运行截图
  9. 9. 命令模式的优点
  10. 10. 适用命令模式的情景
  11. 11. 下载源码请到