设计模式9之命令模式

在开发中 , 方法的请求与方法的执行往往存在紧密耦合关系 , 不利于系统的维护 。 命令模式就是为了解决这个问题而出现的 。
什么是命令模式“
命令模式是一个高内聚的模式 , 其定义为:Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.(将一个请求封装成一个对象 , 从而让你使用不同的请求把客户端参数化 , 对请求排队或者记录请求日志 , 可以提供命令的撤销和恢复功能 。 )

下面为命令模式的通用类图:
设计模式9之命令模式文章插图
命令模式
命令模式主要由3个要素组成:
“Receive接收者:接收命令Command命令角色:封装要执行的命令Invoker调用者:执行命令”
代码实现首先创建一个抽象接收者Receiver
public abstract class Receiver {//抽象接收者 , 定义每个接收者都必须完成的业务public abstract void doSomething();}再创建一个Receiver的实现类ConcreteReceiver1 。 实现类可以有多个 , 如还可以创建ConcreteReceiver2 。
public class ConcreteReceiver1 extends Receiver {@Overridepublic void doSomething() {Console.log("执行ConcreteReceiver1的方法...");}}public class ConcreteReceiver2 extends Receiver {@Overridepublic void doSomething() {Console.log("执行ConcreteReceiver2的方法...");}}然后创建命令类抽象Command
public abstract class Command {//每个命令类都必须有一个执行命令的方法public abstract void execute();}同Receiver一样 , Command也可以有很多实现类 。
public class ConcreteCommand1 extends Command {//对哪个Receiver类进行命令处理private Receiver receiver;//构造函数传递接收者public ConcreteCommand1(Receiver _receiver) {this.receiver = _receiver;}//必须实现一个命令@Overridepublic void execute() {//业务处理this.receiver.doSomething();}}public class ConcreteCommand2 extends Command {//对哪个Receiver类进行命令处理private Receiver receiver;//构造函数传递接收者public ConcreteCommand2(Receiver _receiver) {this.receiver = _receiver;}//必须实现一个命令@Overridepublic void execute() {//业务处理this.receiver.doSomething();}}创建调用者Invoker
public class Invoker {private Command command;//接受命令public void setCommand(Command _command) {this.command = _command;}//执行命令public void action() {this.command.execute();}}测试:
@Testpublic void test() {//首先声明调用者InvokerInvoker invoker = new Invoker();//定义接收者Receiver receiver = new ConcreteReceiver1();//定义一个发送给接收者的命令Command command = new ConcreteCommand1(receiver);//把命令交给调用者去执行invoker.setCommand(command);invoker.action();}【设计模式9之命令模式】测试结果:
执行ConcreteReceiver1的方法...这里Receiver里面的方法就是我们需要用的方法 , 这个方法由Command获取封装 , Invoker去执行 。
关于命令模式的思考调用者不直接调用接收者的方法 , 而是去调用Command的execute() 。 对于调用者来说 , 它不需要知道接收者是谁 。
一般来说 , 命令模式结合其他设计模式 , 会有更好的效果 。
但是命令模式中Command也不能无限扩展 , 如果有N个命令 , 那就会有N个Command子类 , 这样也不是很好 。


推荐阅读