java之命令模式

实际生活中常有的例子,比如银行吧,在早些年,到银行办理业务,一堆人围着大堂经理问,什么业务该去什么地方办理,哎。。。。,一个问题一天要跟上百号人都解释一遍,你好,这个业务呢,你可以去XX柜台咨询一下,那这个业务呢,你可以去XY柜台咨询,有时候,可能出现错误,返回来回问好几遍,好烦哦。。。。,经理是何等的无奈,但为了客户至上的原则,总是微笑,在微笑。何时是解脱之日啊。哈哈,随着科技的发展,经理们终于从这苦难的日子里解脱了,那就是业务办理区取号机,现在简单的操作就可以耐心等候办理,既方便客户,也解脱了经理,真是造福大众的一件好事。根据办理业务的不同,系统自动分发给各自擅长的业务员哪里,按着号码一次处理。言归正传,上面的例子就命令模式的真实写照,业务办理取号机,将客户的对于业务的请求,统一的接纳,进行分类处理,对于不同的业务,安排到不同的业务员手中处理,避免之前繁琐的过程。

命令模式的定义:Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,请求排队或者记录请求日志,可以提供命令的撤销和恢复功能),说白了,就是把请求封装成对象,以统一应对不同的请求,做出响应

命令模式的通用图解命令模式通用图解

解释上述图解的关键词:

 Client:创建一个具体的命令对象(ConcreteCommand1 or ConcreteCommand2 ...)并设定它的接收者(ConcreteReceiver1 or ConcreteReceiver2....), 说白了,就是写个测试类,创建命令对象和接收者对象初始化一个Invoker,测试命令模式。在实际生活中,对于一个系统,有各种不同的请求,系统无法知道,发送来的请求要什么Command处理和这个Command的最终处理者,就需要有一个总代理就像我们项目的接口人(Invoker)一样,某个涉及到项目的问题先问接口人,然后接口人在安排,哪一个功能小组(具体的Command),小组再安排具体谁来处理(具体的Receiver),而一般发问题的一方,都知道是哪个更能模块出了问题,该找谁解决,但我们都有自己的事,如果这来问一下,那来问一下,那还怎么工作。接口人就可以让工作有秩序的进行。这样下来,接收者也就是想我们一样,屌丝码农,不用跟其他项目的人直接打交道,也避免了,很多麻烦,同样也使得我们的工作,更专注,更高效,不是???

Invoker:要求该命令执行这个请求,安排人,解决问题,包括Command的属性参数,Command的set方法,和引用Command的execute()方法实现的Action()方法

Command : 声明执行操作的接口,抽象类,ConcreteCommand 继承该 Command,具体该是用什么操作处理这事?哪个功能小组能处理这事?至少包括一个execute()方法,或者可以加一个Receiver,更抽象一层,那么ConcreteCommand,就好不用包括Receiver,只要初始化就好

ConcreteCommand:将一个接收者对象绑定在某一个动作上,调用接收者的相应操作,以实现Execute的方法,继承自Command,实现execute方法,包括Receiver,用Receiver来实现execute方法

Receiver:知道如何实施和执行一个请求的相关操作,任何类都可可以作为一个接收者,可以是类或者抽象类,抽象类有对应ConcreteReceiver实现

同时注意根据定义,对于Command中应该包括,命令撤销执行和恢复的状态的功能,具体的在Command添加相关方法,在具体实现类中实现即可

代码实现例子:

  1 public class Invoker
  2 {
  3     private Command command;
  4 
  5     /**
  6      * 设置  command
  7      *
  8      * @param command 对 command 进行赋值
  9      */
 10     public void setCommand(Command command)
 11     {
 12         this.command = command;
 13     }
 14     
 15     public void action() 
 16     {
 17         command.execute();
 18     }
 19 }
 20 
 21 public abstract class Command
 22 {
 23     public abstract void execute();
 24 }
 25 
 26 public class ConcreteCommand1 extends Command
 27 {
 28     private Receiver receiver;
 29     /** 
 30      * @param receiver 
 31      */ 
 32     public ConcreteCommand1(Receiver receiver)
 33     {
 34         this.receiver = receiver;
 35     }
 36 
 37     /** { @inheritDoc } */
 38     public void execute()
 39     {
 40         receiver.doSomething();
 41     }
 42 
 43 }
 44 
 45 public class ConcreteCommand2 extends Command
 46 {
 47     private Receiver receiver;
 48     /** 
 49      * @param receiver 
 50      */ 
 51     public ConcreteCommand2(Receiver receiver)
 52     {
 53         this.receiver = receiver;
 54     }
 55 
 56     /** { @inheritDoc } */
 57     @Override
 58     public void execute()
 59     {
 60         receiver.doSomething();
 61     }
 62 
 63 }
 64 
 65 public abstract class Receiver
 66 {
 67     public abstract void doSomething();
 68 }
 69 
 70 public class ConcreteReceiver1 extends Receiver
 71 {
 72 
 73     /** { @inheritDoc } */
 74     @Override
 75     public void doSomething()
 76     {
 77         // TODO Auto-generated method stub
 78     }
 79 
 80 }
 81 
 82 public class ConcreteReceiver2 extends Receiver
 83 {
 84 
 85     /** { @inheritDoc } */
 86     @Override
 87     public void doSomething()
 88     {
 89         // TODO Auto-generated method stub
 90     }
 91 
 92 }
 93 
 94 public class Client
 95 {
 96     public static void main(String[] args)
 97     {
 98         // 首先声明调用者Invoker
 99         Invoker invoker = new Invoker();
100         // 定义接收者
101         Receiver receiver = new ConcreteReceiver1();
102         // 定义一个发送给接收者的命令
103         Command command = new ConcreteCommand1(receiver);
104         // 把命令交给调用者去执行
105         invoker.setCommand(command);
106         invoker.action();
107     }
108 }

命令模式的优缺点

优点1.将调用操作的对象与知道如何实现该操作的对象解耦,请求与具体实现相解耦

   2.Command是头等的对象,他可以像其他对象一样被操作和扩展,易扩展,你可以很容易的添加Command而不需要改变现有的类,也可以很轻松的将多个Command装配成一个复合的命令

 缺点几乎都要针对不同的命令,新增不同的类,增加系统复杂度

 

posted @ 2017-10-06 00:37  朱洪昌  阅读(451)  评论(0编辑  收藏  举报