行为型模式之命令模式
1. 简介
命令模式(Command Pattern)主要就是说将命令抽象化成对象,使得命令的发起者和命令的执行者进行解耦,两者之间通过命令交互,这样方便对命令进行管理。
简单来说,就是将执行命令抽象化成对象进行管理,比如我们可以将要执行的命令保存到队列中,队列依次执行相应的命令。
2. 角色描述
Command
- 命令抽象化的接口,一般会定义命令的执行方法。ConcreteCommand
- 实际具体的命令对象,一般命令对象会与命令的执行者产生组合依赖,方便执行者执行命令。Receiptor
- 接收者,命令执行者的抽象化对象。ConcreteReceiptor
- 实际的命令的接收者,真正负责命令的执行。Invokor
- 命令的发起者。
3. 代码演示
场景描述:
此时我们就依赖命令模式的角色进行简单实现。
3.1 类图
3.2 代码
package com.inconspicuousy.pattern.command;
import java.util.concurrent.ConcurrentLinkedQueue;
// 命令抽象化
interface Command {
void execute();
}
// 命令接收者(命令实际的执行者)
abstract class Receiptor {
// 具体的执行操作
public abstract void action();
}
// 实际名的命令对象
class ConcreteCommandA implements Command{
// 实际命令对象,一般命令都会与执行者进行组合依赖
private final Receiptor receiptor;
public ConcreteCommandA(Receiptor receiptor) {
this.receiptor = receiptor;
}
@Override
public void execute() {
System.out.println("ConcreteCommandA 开始执行命令");
receiptor.action();
System.out.println("ConcreteCommandA 命令执行结束");
}
}
// 实际命令的接收者(执行者)
class ConcreteReceiptor extends Receiptor {
@Override
public void action() {
System.out.println("ConcreteReceiptor 执行命令");
}
}
// 命令的调用者,负责发起命令
class Invoker {
// 模拟中间件, 线程安全的链表队列
private static final ConcurrentLinkedQueue<Command> QUEUE = new ConcurrentLinkedQueue();
static {
// 开启一个线程模拟从队列中取出命令并执行
new Thread(() -> {
while (true) {
Command poll = QUEUE.poll();
if (poll != null) {
poll.execute();
}
}
}).start();
}
// 指定对应的命令
private Command command;
public Invoker(Command command) {
this.command = command;
}
public void setCommand(Command command) {
this.command = command;
}
// 当发起命令时, 将命令存储到队列中
public void call() {
QUEUE.add(command);
}
}
/**
* 命令模式-代码示例
* @author peng.yi
*/
public class CommandTest {
public static void main(String[] args) {
ConcreteReceiptor concreteReceiptor = new ConcreteReceiptor();
ConcreteCommandA Command = new ConcreteCommandA(concreteReceiptor);
Invoker invoker = new Invoker(Command);
invoker.call();
// 在创建2个命令
ConcreteCommandA Command1 = new ConcreteCommandA(concreteReceiptor);
ConcreteCommandA Command2= new ConcreteCommandA(concreteReceiptor);
invoker.setCommand(Command1);
invoker.call();
invoker.setCommand(Command2);
invoker.call();
}
}
3.3 测试结果
ConcreteCommandA 开始执行命令
ConcreteReceiptor 执行命令
ConcreteCommandA 命令执行结束
ConcreteCommandA 开始执行命令
ConcreteReceiptor 执行命令
ConcreteCommandA 命令执行结束
ConcreteCommandA 开始执行命令
ConcreteReceiptor 执行命令
ConcreteCommandA 命令执行结束