定义
将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。也称之为动作Action模式,事务Transaction模式。
结构图
Invoker:要求该命令执行这个请求,是请求的发送者,通过命令对象执行请求。一个调用者并不需要在设计时确定其接收者,因此它只与抽象命令之间存在关联,在程序运行时,将调用命令对象的execute方法,间接调用接收者的方法。
Command:用来申明执行操作的接口;
Receiver:知道如何实施与执行一个请求相关的操作,任何类都可能成为一个接收者;
ConcreteCommand:将一个接收者对象绑定于一个动作,调用接收者相应的操作,以实现Execute。
Client:在客户类中需要创建调用者对、具体命令类对象,在创建具体命令对象时指定对应的接收者。发送者和接收者之间没有直接联系,都通过命令对象间接调用。
代码实现
- Receiver接收者
/**
* User:tumbler
* Desc:命令模式--接收者-真正的命令执行者
*/
public class Receiver {
public void action() {
System.out.println("Receiver.action()");
}
}
- Command命令接口
/**
* User:tumbler
* Desc:命令模式--命令接口
*/
public interface Command {
/**
* 在实际项目中,可以根据具体需求定义多个不同的方法
*/
void execute();
}
- ConcreteCommand具体命令
/**
* User:tumbler
* Desc:命令模式--具体命令类,实现Command接口,
* 绑定一个接收者(具体执行命令者)
*/
public class ConcreteCommand implements Command {
//命令的真正执行者
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
//命令执行前后都可以执行其他操作
receiver.action();
}
}
- Invoker命令的发起者
/**
* User:tumbler
* Desc:命令模式--命令的调用者和发起者
* 持有Command
*/
public class Invoker {
//可通过容器List<Command>容纳很多命令对象进行批处理,数据库底层的事务管理就是类似的结构
private Command command;
public Invoker(Command command) {
this.command = command;
}
/**
* 业务方法,调用命令类的方法,可在调用前和后做相应的处理
*/
public void call() {
command.execute();
}
}
- Client测试类
/**
* User:tumbler
* Desc:命令模式--测试
*/
public class Client {
public static void main(String[] args) {
Command command = new ConcreteCommand(new Receiver());
Invoker invoker = new Invoker(command);
invoker.call(); //Receiver.action()
}
}
开发中常见应用
- Struts2中,action的整个调用过程中就有命令模式
- 数据库事务机制的底层实现
- 命令的撤销和恢复
总结
- 可以较容易的设计一个命令队列
- 在需要的情况下,可以较容易的将命令记录日志
- 允许接收请求的一方是否要否决请求
- 可以容易的实现对请求的撤销和重做
- 加进具体新的命令不会影响其他的类
- 把请求一个操作的对象与具体执行操作的对象分离开来