简介
命令模式属于对象的行为模式。命令模式又称为行动(Action)模式或交易(Transaction)模式。
命令模式把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
将来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化。用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化。分离变化与不变的因素。在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;设置调用参数;调用目标对象的方法。
但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作command类。
角色
命令(Command)角色:声明了一个给所有具体命令类的抽象接口。
具体命令(ConcreteCommand)角色:定义一个接收者和行为之间的弱耦合;实现execute()方法,负责调用接收者的相应操作。execute()方法通常叫做执行方法。
请求者(Invoker)角色:负责调用命令对象执行请求,相关的方法叫做行动方法。
接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。
客户端(Client)角色:创建一个具体命令(ConcreteCommand)对象并确定其接收者。
类图
案例
命令(Command)角色
public interface Command { void execute(); }
具体命令(ConcreteCommand)角色
public class ConcreteCommand implements Command { //持有相应的接收者对象 private Receiver receiver = null; public ConcreteCommand(Receiver receiver) { this.receiver = receiver; } @Override public void execute() { receiver.action(); } }
请求者(Invoker)角色
//执行者 public class Invoker { /** * 持有命令对象 */ private Command command = null; public Invoker() { } public void setCommand(Command command) { this.command = command; } public void action() { command.execute(); } }
接收者(Receiver)角色
//接收者 public class Receiver { public void action() { System.out.println("行为"); } }
客户端(Client)角色
public class Client { public static void main(String[] args) { //创建接收者 Receiver receiver = new Receiver(); //创建命令对象,设定它的接收者 Command command = new ConcreteCommand(receiver); //创建请求者 Invoker invoker = new Invoker(); //命令对象设置进去 invoker.setCommand(command); //执行方法 invoker.action(); } }
优缺点
优点
1.降低对象之间的耦合度。
2.可扩展性:新的命令可以很容易地加入到系统中。
3.可以比较容易地设计一个组合命令(宏)。
4.调用同一方法实现不同的功能,更动态的控制。
缺点
使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。
适用情况
1.系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
2.系统需要在不同的时间指定请求、将请求排队和执行请求。
3.系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
4.系统需要将一组操作组合在一起,即支持宏命令。
Head First 设计模式(中文版)的示例:
码云地址:https://gitee.com/manusas/CommandDP
大自然的搬运工(thx 以下作者):
hxxp://blog.csdn.net/jason0539/article/details/45110355
hxxps://www.cnblogs.com/devinzhang/archive/2012/01/06/2315235.html
hxxps://www.cnblogs.com/java-my-life/archive/2012/06/01/2526972.html