1、概念
命令模式是为了将请求发起者和请求处理者解耦,从而提高请求的处理效率。
请求发起者和请求处理者有许多同义词,例如生产者和消费者,client和Server。
命令模式涉及到四个角色,掌握它们之间的关系和职责是掌握命令模式的核心。
- Client:请求发起者。
- Command:它代表请求的类型。
- Invoker:它代表请求的协调者。
- Receiver:请求处理者。
为了更方便的理解命令模式,结合生活中的点餐场景。当我们进入餐馆点餐时,
- 顾客就是请求发起者,他点了一种食物。
- 菜单就是请求类型列表,顾客点的食物对应具体的请求类型。
- 服务员将我们的食物告知厨师,服务员扮演着Invoker的角色。
- 厨师为我们做饭,他扮演着请求处理者的角色。
2、UML图

3、代码
ICommand代表请求的类型,它的实现类与Receiver的关系为组合关系。
/**
*
* @Title: ICommand.java
* @Package command
* @Description: 扮演着点餐场景中菜单的角色,在命令模式代表请求的类型
* @version V1.0
*/
public interface ICommand {
void doSomething();
}
CommandTypeA,代表一种具体的请求类型。
/**
*
* @Title: CommandTypeA.java
* @Package command
* @Description: 代表一种具体的请求类型,这里抽象为TypeA
* @version V1.0
*/
public class CommandTypeA implements ICommand {
// 组合关系,它是必备的属性
private Receiver receiver;
public CommandTypeA(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void doSomething() {
receiver.dealTypeA();
}
}
Invoker,扮演着协调者的角色,主要是将Command传递给请求处理者。
/**
*
* @Title: Invoker.java
* @Package command
* @Description: 在点餐场景中扮演着服务员的角色,在命令模式中扮演着协调者的角色
* @version V1.0
*/
public class Invoker {
public void invoke(ICommand command) {
command.doSomething();
}
}
Receiver,它代表着请求处理者的角色。
/**
*
* @Title: Receiver.java
* @Package command
* @Description: 扮演着请求处理者的角色,在点餐场景中扮演着厨师的角色
* @version V1.0
*/
public class Receiver {
public void dealTypeA() {
System.out.println("正在处理A类型的请求");
}
}
Client,它扮演着请求发起者的角色。
/**
*
* @Title: Client.java
* @Package command
* @Description: 扮演着请求发起者的角色,在点餐模型中扮演着顾客的角色
* @version V1.0
*/
public class Client {
public static void main(String[] args) {
// 创建请求处理者,厨师
Receiver receiver = new Receiver();
// 创建具体的请求类型
ICommand command = new CommandTypeA(receiver);
// 创建协调者,服务员
Invoker invoker = new Invoker();
// 处理真正的请求
invoker.invoke(command);
}
}
4、代码
在使用命令模式时,需要注意:
请求类型CommandTypeA与Receiver是组合关系,只能通过构造器方式注入依赖。
命令模式本质是为了将请求者和处理者解耦,所以大部分情况下请求都是异步方式进行的,有的可以添加请求队列,设置优先级等等,所以对于某些实时性的请求并不适合。
5、示例
生产者与消费者模型。