版权声明:本文为博主原创,未经博主允许不得转载。 https://blog.csdn.net/weixin_36904568/article/details/89929165
1. 定义
又称为行动模式或交易模式。把一个请求或者操作封装到一个对象中,允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志可以提供命令的撤销和恢复功能。
- 发出命令的责任:请求的一方发出请求要求执行一个命令
- 执行命令的责任:接收的一方收到请求,并执行操作
- 由协调者在中间进行协调
使用
- 具体接受者
- 具体接受动作
- 抽象命令接口
- 具体命令对象
- 使用堆栈记录过去的状态
- 接受者
- 公开执行方法(接受者需要执行的动作集合)
- 公开撤销方法(状态出栈,接受者执行返回到该状态的对应动作集合)
- 协调者
- 使用堆栈记录过去的状态
- 保存多个命令对象
- 执行命令:命令对象中的函数
- 调用接受者的动作
- 当前的命令入栈
- 撤销命令
- 命令出栈,调用其撤销动作
- 业务
- 客户把封装了具体接受者的具体命令对象传递给调用者
- 调用者执行命令(命令对象中的函数),调用接受者的动作
(1)接受者
package CommandPattern;
/**
* 接受者A
*/
public class ReceiverA {
public static final int MAX = 1;
public static final int MIN = 0;
//状态
private int states;
public ReceiverA(){
this.states = MIN;
}
//操作
public void actionToMax(){
System.out.println("A接收到命令并将其变大");
this.states = MAX;
}
//操作
public void actionToMin(){
System.out.println("A接收到命令并将其变小");
this.states = MIN;
}
public int getStates() {
return states;
}
}
(2)命令
package CommandPattern;
/**
* 抽象命令
*/
public interface Command {
//执行命令
public void execute();
//撤销命令
public void undo();
}
package CommandPattern;
import java.util.Stack;
/**
* 具体命令A
*/
public class CommandA_MAX implements Command {
private ReceiverA receiverA;
private Stack<Integer> stack;
public CommandA_MAX(ReceiverA receiverA) {
this.receiverA = receiverA;
stack = new Stack<>();
}
//让接受者执行相关的操作
@Override
public void execute() {
//记录当前状态,方便撤销
stack.push(receiverA.getStates());
receiverA.actionToMax();
}
//让接受者撤销操作
@Override
public void undo() {
int state = stack.pop();
switch (state) {
case ReceiverA.MIN:
receiverA.actionToMin();
break;
case ReceiverA.MAX:
receiverA.actionToMax();
break;
}
}
}
package CommandPattern;
import java.util.Stack;
/**
* 具体命令A
*/
public class CommandA_MIN implements Command {
private ReceiverA receiverA;
private Stack<Integer> stack;
public CommandA_MIN(ReceiverA receiverA) {
this.receiverA = receiverA;
stack = new Stack<>();
}
//让接受者执行相关的操作
@Override
public void execute() {
//记录当前状态,方便撤销
stack.push(receiverA.getStates());
receiverA.actionToMin();
}
//让接受者撤销操作
@Override
public void undo() {
int state = stack.pop();
switch (state) {
case ReceiverA.MIN:
receiverA.actionToMin();
break;
case ReceiverA.MAX:
receiverA.actionToMax();
break;
}
}
}
(3)协调者
package CommandPattern;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
* 协调者
*/
public class Invoker {
private List<Command> commands;
private Stack<Command> stack;
public Invoker(){
stack = new Stack<>();
commands = new ArrayList<>();
}
public void setCommand(Command command) {
commands.add(command);
}
//执行对应的命令
public void invoke(int i){
Command command = commands.get(i);
stack.push(command);
command.execute();
}
//撤销命令
public void unInvoke(){
Command command = stack.pop();
command.undo();
}
}
(4)测试
package CommandPattern;
public class Test {
public static void main(String[] args) {
ReceiverA receiverA = new ReceiverA();
CommandA_MAX commandA_max = new CommandA_MAX(receiverA);
CommandA_MIN commandA_min = new CommandA_MIN(receiverA);
Invoker invoker = new Invoker();
invoker.setCommand(commandA_max);
invoker.setCommand(commandA_min);
invoker.invoke(0);
invoker.unInvoke();
invoker.invoke(1);
invoker.unInvoke();
}
}
3. 特点
- 容易扩展新的命令
- 较容易地设计一个命令队列
- 容易地实现对请求的撤销和恢复
- 较容易地将命令记入日志
4. 宏命令
宏命令作为一个包含了一组具体命令的具体命令
- 在执行宏命令时,执行它包含的所有命令
- 在撤销宏命令时,撤销它包含的所有命令
package CommandPattern;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
* 宏命令,一次性执行所有命令
*/
public class MacroCommand implements Command{
private List<Command> commands;
private Stack<Command> stack;
public MacroCommand(){
commands = new ArrayList<>();
stack = new Stack<>();
}
public void setCommand(Command command) {
commands.add(command);
}
@Override
public void execute() {
for (Command command:
commands) {
command.execute();
stack.push(command);
}
}
@Override
public void undo() {
while (!stack.isEmpty()){
Command command = stack.pop();
command.undo();
}
}
}
5. 队列请求
工作队列存放一系列命令,线程从队列中取出命令并执行,然后再执行下一条命令
可以有效限制线程数目
6. 日志请求
- 命令在执行的时候,通过记录方式,将日志存储在磁盘上
- 系统异常时,命令利用磁盘的日志,通过加载方式,重新加载对象并执行命令