命令模式(Command Pattern): 将一个请求封装成一个对象, 从而可以用不同请求对客户进行参数化, 对请求队列或者记录请求日志, 以及支持可撤销的操作.
设计模式-概述
命令模式实现了请求的发送者与请求的执行者完全解耦, 发送者与执行者之间没有直接引用关系, 中间由命令来连接, 发送方不用了解执行过程.
结构 命令模式有4个成员:
Command(抽象命令类)
ConcreteCommand(具体命令类)
Invoker(调用者)
Receiver(接收者)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 @startuml command-1 !include common.cuml Class(Receiver,"接收者") { + action() : void } Class(Command,"抽象命令接口") <<abstract>> { + execute() : void } Class(ConcreteCommand,"具体命令类") { - state : State + execute() : void } Class(Invoker,"调用者") { + call() : void } Class(Client,"客户端") { } note AS N1 receiver.action(); end note Receiver <-left- ConcreteCommand : receiver ConcreteCommand .up.|> Command Invoker o-right-> Command N1 -up- ConcreteCommand Client .right.> Invoker : 2 Client .right.> ConcreteCommand : 1 @enduml
使用时序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @startuml command-2 !include common.cuml participant Client as U participant Receiver as R participant ConcreteCommand as C participant Invoker as I U --> R : new Recever(); activate U U -> C : new ConcreteCommand(receiver) U -> I : new Invoker(command) deactivate U U --> I : call() activate I activate U I --> C : execute() activate C C --> R : action() activate R @enduml
命令队列与宏命令
命令队列 Invoke
角色内的成员可以替换为CommandQueue
, 来实现命令队列方式的执行.
CommandQueue
内部成员变量是一个 List<Command>
, execute()
方法通过for循环依次执行command
对象的execute()
方法.
宏命令 与命令队列不同的是, 它的commond
本身内部可以保存一个command
集合, 一组命令可以包含在一个command
中.
代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 public class Client { public static void main (String[] args) { Receiver receiver = new Receiver (); ConcreteCommand concreteCommand = new ConcreteCommand (receiver); Invoke invoke = new Invoke (concreteCommand); invoke.execute(); } } class Invoke { private Command command; Invoke(Command command) { this .command = command; } public void execute () { command.execute(); } } class Receiver { public void action () { System.out.println("执行操作" ); } } abstract class Command { public abstract void execute () ; } class ConcreteCommand extends Command { private Receiver receiver; ConcreteCommand(Receiver receiver) { this .receiver = receiver; } @Override public void execute () { receiver.action(); } }
使用场景
需要请求者和请求接收者解耦, 使得调用者和接收者不直接交互.
调用者和接收者生命期可以不同, 调用者不存在, 接收者也可以是活动的.
如果需要指出撤销和恢复操作
如果有一组命令需要合并成宏命令
具体应用 Spring Cloud Hystrix 使用命令模式来执行请求.