命令模式又称:行动模式 或 交易模式
使用了命令模式,客户端就不在直接与Receiver
打交道,而把执行的细节交于Invoker
处理,ConcreteCommand
封装了具体的细节.
实现命令模式的轻重之分:
轻就是它只提供一个和接收之间的耦合而已
重就是应当实现所有细节,这时就不再需要接收者了.
我们也可以用一个具体命令者ConcreteCommand
动态的调用其Receiver
处理某一个事项.
上类图:

实例:Java JWT的事件处理,录音机的功能
-
示例代码:
- 创建命令的抽象接口
package com.byedbl.command.method2;
/**
* 命令角色,声明了一个所有的命令类需要实现的接口
*/
public interface Command {
void execute();
}
- 实现一个具体 的命令
package com.byedbl.command.method2;
/**
* 具体命令角色,实现了声明的命令接口
*/
public class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
public void execute() {
receiver.action();
}
}
- 创建一个命令接收者
package com.byedbl.command.method2;
/**
* 负责具体实施和 执行一个请求
*/
public class Receiver {
/**
* 行动方法
*/
public void action() {
System.out.println("receive a command");
}
}
- 负责调用命令的对象
Invoker
package com.byedbl.command.method2;
/**
*负责调用命令对象执行请求
*/
public class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
/**
* 这个叫行动方法
*/
public void action() {
command.execute();
}
}
- 客户端调用
package com.byedbl.command.method2;
import static org.junit.Assert.*;
/**
* <pre>
* 客户角色,创建一个具体命令,并确定其 接收者
*
* 为什么不直接将Receiver注册到Invoker里面?而要先注册到Command里面?
* 假设我们现在直接将Receiver注册到Invoker里面,那么Invoker的 action方法怎么调Receiver的方法呢?要知道Invoker是可以没有一个通用的接口的.
* 我们发现只能重写一个Invoker了.
* 那我们抽象一个接口,比如现在的Command,command的里面有一个给Invoker调用的方法execute,
* 这时我们Invoker就能得到很好的重用,也符合开闭原则,
* 当我们要调用一个其他的动作时,我们只要实现一个Command 的接口即可,实现的Command可以简单的委托给Receiver处理,
* 极端情况也可以不要Receiver,具体的Command就处理了全部的逻辑.这时模式就变成了一堆不同命令的策略模式+一个Invoker
*
* 那为什么不 直接用策略模式呢?
* 关键是多了个Invoker类,这个调用各种策略的通用类,可以说是在策略模式上更进了一步,
* 告诉了我们怎么通用调用策略的方法(不仅仅是可以用反射)
*
* 用途场景:undo 功能
*/
public class CommandTest {
@org.junit.Test
public void execute() {
Receiver receiver = new Receiver();
Command command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker(command);
invoker.action();
}
}
-
优点
- 把请求一个操作对象
Invoker
与知道怎么执行一个操作的对象Receiver
分隔开
网友评论