概念
将一系列方法调用封装,用户只需调用一个方法执行,这些封装好的方法就会被挨个执行调用。通常是将请求封装成一个对象,对请求进行排队以支持撤销等动作。优点也是降低耦合,但同时导致类膨胀。类似于java线程池中的队列,工作队列只负责取出任务,执行execute方法,不关心传入什么。
使用场景
- 将待执行的动作以参数的形式抽象出来
- 支持事务操作,记录和取消操作
实现方式
- 命令角色(Command):定义命令的接口,声明执行的方法。
- 具体命令角色(Concrete Command):实现命令接口,是“虚”的实现;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。我们可以有多个具体命令角色提供不同的命令。
- 接收者角色(Receiver):负责具体实施和执行一个请求。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
- 请求者(调用者)角色(Invoker):负责调用命令对象执行请求。在请求者中可维持一个数据结构记录执行过哪些命令。
- 客户角色(Client):创建一个具体命令对象并设定该命令对象的接收者
/**
具体接受者
**/
public class Receiver {
// 洗手
public void actionWashing(){
System.out.println("执行洗手操作");
}
// 吃饭
public void actionEat(){
System.out.println("执行吃饭操作");
}
}
/**
抽象命令
**/
public interface Command {
void execute();
}
/**
洗手命令
**/
public class WashCommand implements Command {
private Receiver receiver;
public WashCommand(Receiver receiver){
this.receiver = receiver;
}
@Override
public void execute(){
receiver.actionWashing();
}
}
/**
吃饭命令
**/
public class EatCommand implements Command {
private Receiver receiver;
public EatCommand(Receiver receiver){
this.receiver = receiver;
}
@Override
public void execute(){
receiver.actionEat();
}
}
/**
命令请求调度者(管理各个命令之间的执行顺序)
**/
public class Invoker {
private List<Command> commands = new ArrayList<Command>();
public addCommand(Command command) {
commands.add(command);
}
public void executeActions(){
for(Command c : commands) {
c.execute();
}
}
}
public class Client{
public static void main(String[] args){
Receiver receiver = new Receiver();
Invoker invoker = new Invoker();
invoker.addCommand(new WashCommand(receiver));
invoker.addCommand(new EatCommand(receiver));
invoker.action();
}
}