文章目录
- 前言
- 正文
-
- 一、命令模式的设计概念
- 二、Java代码示例
-
- [2.1 Command](#2.1 Command)
- [2.2 LsCommand](#2.2 LsCommand)
- [2.3 MkdirCommand](#2.3 MkdirCommand)
- [2.4 Receiver](#2.4 Receiver)
- [2.5 DefaultReceiver](#2.5 DefaultReceiver)
- [2.6 Invoker](#2.6 Invoker)
- 三、测试
-
- [3.1 Client](#3.1 Client)
- [3.2 测试结果](#3.2 测试结果)
- 四、命令模式的小结
-
- [4.1 适用性](#4.1 适用性)
- [4.2 总结](#4.2 总结)
前言
命令模式(Command Pattern)是 23种设计模式之一,属于行为型设计模式。
命令模式把一个请求或者操作封装到一个对象中。
命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
正文
一、命令模式的设计概念
命令模式包含有5个角色。如下图:
-
抽象命令角色(Command):声明执行操作的接口。
-
具体命令角色(ConcreteCommand):将一个接收者对象绑定于一个动作,调用接收者相应的操作以实现Execute。
-
请求者角色(Invoker):负责调用相关的命令体执行请求。
-
接收者角色(Receiver):负责具体实施和执行某一个请求。
二、Java代码示例
依据第一节的类图,进行代码实现。有部分变更调整。
代码结构如下:
2.1 Command
java
package org.feng;
/**
* 命令接口
*
* @author feng
*/
public interface Command {
/**
* 执行命令
*/
void execute();
}
2.2 LsCommand
java
package org.feng;
/**
* ls命令
*
* @author feng
*/
public class LsCommand implements Command {
private final Receiver receiver;
public LsCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.ls();
}
}
2.3 MkdirCommand
java
package org.feng;
/**
* mkdir命令
*
* @author feng
*/
public class MkdirCommand implements Command {
private final Receiver receiver;
public MkdirCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.mkdir();
}
}
2.4 Receiver
java
package org.feng;
/**
* 命令接收者
*
* @author feng
*/
public interface Receiver {
default void ls() {
System.out.println("执行【ls】命令");
}
default void mkdir() {
System.out.println("执行【mkdir】命令");
}
}
2.5 DefaultReceiver
java
package org.feng;
/**
* 默认的命令接收者
*
* @author feng
*/
public class DefaultReceiver implements Receiver {
}
2.6 Invoker
java
package org.feng;
/**
* 请求者
*
* @author feng
*/
public class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void executeCommand() {
this.command.execute();
}
public void setCommandAndExecute(Command command) {
setCommand(command);
executeCommand();
}
}
三、测试
3.1 Client
java
package org.feng;
/**
* 测试-客户端
*
* @author feng
*/
public class Client {
public static void main(String[] args) {
Receiver receiver = new DefaultReceiver();
Command ls = new LsCommand(receiver);
Command mkdir = new MkdirCommand(receiver);
Invoker request = new Invoker();
request.setCommandAndExecute(ls);
request.setCommandAndExecute(mkdir);
}
}
3.2 测试结果
执行【ls】命令
执行【mkdir】命令
四、命令模式的小结
4.1 适用性
-
命令模式适用于操作请求能够被当作是命令的情况
-
命令模式适用于系统需要支持回退或者撤销某操作的情况
4.2 总结
命令模式将命令的请求者和命令的处理者分开来,命令的请求者也不清楚请求的命令由哪个对象来执行,也不知道具体实现的操作是怎么样的。
命令模式可以将命令组合起来形成一个复杂的宏命令,这样可以通过一个命令来实现一系列化的操作。
由于命令的发起者和命令的处理者完全解耦,所以命令模式有很好的扩展性,要扩展新的命令只需要添加新的命令类然后再客户端调用的时候动态的将其装载进去就可以了。
由于命令模式针对每一个命令都会新建一个类去包装形成一个对象,这样在系统的逐步扩大的过程中会形成许多的命令类使得系统更加复杂并且增加内存的消耗。