在软件开发中,我们经常需要向某些对象发送请求(调用其中的某个或某些方法),但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,此时,我们特别希望能够以一种松耦合的方式来设计软件,使得请求发送者与请求接收者能够消除彼此之间的耦合,让对象之间的调用关系更加灵活,可以灵活地指定请求接收者以及被请求的操作。命令模式为此类问题提供了一个较为完美的解决方案。
命令模式可以将请求发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。
命令模式定义如下:
命令模式(Command Pattern):将一个请求封装为一个对象,从而让我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。
命令模式的定义比较复杂,提到了很多术语,例如“用不同的请求对客户进行参数化”、“对请求排队”,“记录请求日志”、“支持可撤销操作”等,在后面我们将对这些术语进行一一讲解。
命令模式的核心在于引入了命令类,通过命令类来降低发送者和接收者的耦合度,请求发送者只需指定一个命令对象,再通过命令对象来调用请求接收者的处理方法
命令发出者与命令接收者之间实现松耦合。
实例:简易计算器
计算器界面类CalculatorForm充当请求发送者,实现了数据求和功能的加法类Adder充当请求接收者,界面类可间接调用加法类中的add()方法实现加法运算,并且提供了可撤销加法运算的undo()方法。
代码:
抽象命令类:
public abstract class AbstractCommand {
public abstract int excute(int value);
public abstract int undo();
}
具体命令类:
public class ConcreteCommand extends AbstractCommand {
private Add add = new Add();
private int value;
@Override
public int excute(int value) {
this.value = value;
return add.add(this.value);
}
@Override
public int undo() {
return add.add(-value);
}
}
具体接收者:
public class Add {
private int num =0;
public int add(int value){
num += value;
return num;
}
}
请求发送者:
public class CaculateForm {
private AbstractCommand command;
public void setCommand(AbstractCommand command){
this.command = command;
}
public void comput(int value){
int i = command.excute(value);
System.out.println("after add the result is :"+ i);
}
public void undo(){
int i = command.undo();
System.out.println("after undo the result is :"+ i);
}
}
测试代码:
CaculateForm ca = new CaculateForm();
AbstractCommand com = new ConcreteCommand();
ca.setCommand(com);
ca.comput(3);
ca.comput(4);
ca.undo();
ca.undo();