zoukankan      html  css  js  c++  java
  • 《JAVA与模式》之命令模式

    意图:将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化;对请求排队或记录日志,以及支持可撤销的操作
    动机:将”发出请求的对象”和”接收与执行这些请求的对象”分隔开来。

    这里可能会有一个疑惑,就是为什么要将”发出请求的对象”和”接收与执行这些请求的对象”分隔开来,其实道理很简单,

    我们假设司令发布一个命令,你说他老人家会直接走到兵营跟战士们说,明天我们要如何如何打,当然是将命令通知给相关人员(命令接收者)

    让其来通知。

    角色关系:

    1)、Command
      声明执行操作的接口
    2)、ConcreteCommand
      将一个接收者对象绑定于一个动作
      调用接收者相应的操作,以实现execute
    3)、Client
      创建一个具体命令对象并设定它的接收者
    4)、Invoker
      要求该命令执行这个请求
    5)、Receiver
      知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者
    结构图:

    协作:
    1)、client创建一个ConcreteCommand对象并指定它的Receiver对象
    2)、某Invoker对象存储该ConcreteCommand对象
    3)、该Invoker通过调用Command对象的execute操作来提交一个请求。若该命令是可撤销的,ConcreteCommand在执行execute操作前存储当前状态以用于取消该命令
    4)、ConcreteCommand对象调用它的Receiver的操作以执行该请求
    命令对象将动作和接受者包进对象中,这个对象只暴露出一个execute()方法,当此方法被调用的时候,接收者就会进行这些动作。从外面来看,其他对象不知道究竟哪个接收者进行了哪些动作,只知道如果调用execute()方法,请求的目的就能达到。 

    ------------

    具体代码

     1     public static void main(String[] args) {
     2 
     3         //命令执行者
     4         Receiver receiver = new Receiver();
     5         //具体命令
     6         Command command = new ConcreteCommand(receiver);
     7         //命令发起者
     8         Invoker invoker=new Invoker();
     9         invoker.setCommand(command);
    10         invoker.runCommand();//发布命令通知
    11 
    12     }
    13 
    14 }
    15 
    16 // 命令接口
    17 interface Command {
    18 
    19     // 执行命令
    20     public void doCommand();
    21 
    22     // 撤销命令
    23     public void undoCommand();
    24 
    25 }
    26 //具体命令
    27 class ConcreteCommand implements Command {
    28 
    29     private Receiver receiver;
    30     private String state;// 命令执行状态
    31 
    32     public ConcreteCommand(Receiver receiver) {
    33 
    34         this.receiver = receiver;
    35     }
    36 
    37     public void doCommand() {
    38         state = "执行中....";
    39         receiver.action();
    40 
    41     }
    42 
    43     public void undoCommand() {
    44         // TODO Auto-generated method stub
    45         state = "";
    46         receiver.backaction();
    47     }
    48 
    49 }
    50 
    51 /**
    52  * 命令接收者 真正执行命令的对象
    53  */
    54 class Receiver {
    55 
    56     public void action() {
    57 
    58         System.out.println("执行命令");
    59     }
    60 
    61     public void backaction() {
    62 
    63         System.out.println("撤销命令");
    64     }
    65 
    66 }
    67 //命令发起者
    68 class Invoker {
    69 
    70     private Command command = null;
    71 
    72     public Command getCommand() {
    73         return command;
    74     }
    75 
    76     public void setCommand(Command command) {
    77         this.command = command;
    78     }
    79 
    80     public void runCommand() {
    81         command.doCommand();
    82     }
    83 
    84 }
    命令模式的优点
    1:更松散的耦合
    2:更动态的控制
    3:能很自然的复合命令
    4:更好的扩展性
       在命令模式中,请求者(Invoker)不直接与接收者(Receiver)交互,即请求者(Invoker)不包含接收者(Receiver)的引用,因此彻底消除了彼此之间的耦合。
       命令模式满足“开-闭原则”。如果增加新的具体命令和该命令的接受者,不必修改调用者的代码,调用者就可以使用新的命令对象;反之,如果增加新的调用者,不必修改现有的具体命令和接受者,新增加的调用者就可 以使用已有的具体命令。
     
    命令模式的本质  
    命令模式的本质是: 封装请求
    何时选用命令模式
    1:如果需要抽象出需要执行的动作,并参数化这些对象,可以选用命令模式,把这些需要执行的动作抽象成为命令,然后实现命令的参数化配置
    2:如果需要在不同的时刻指定、排列和执行请求,可以选用命令模式,把这些请求封装成为命令对象,然后实现把请求队列化
    3:如果需要支持取消操作,可以选用命令模式,通过管理命令对象,能很容易的实现命令的恢复和重做的功能
    4:如果需要支持当系统崩溃时,能把对系统的操作功能重新执行一遍,可以选用命令模式,把这些操作功能的请求封装成命令对象,然后实现日志命令,就可以在系统恢复回来后,通过日志获取命令列表,从而重新执行一遍功能
    5:在需要事务的系统中,可以选用命令模式,命令模式提供了对事务进行建模的方法,命令模式有一个别名就是Transaction。
     
        模式的结构中包括四种角色: 
     接收者(Receiver)
     命令(Command)接口
     具体命令(ConcreteCommand)
     请求者(Invoker)
    java <wbr>命令模式

     

     

    参考:

    http://blog.sina.com.cn/s/blog_a0fb290c01017f3m.html

    http://www.cnblogs.com/ikuman/archive/2013/08/06/3233092.html

    http://www.cnblogs.com/devinzhang/archive/2012/01/06/2315235.html

    http://blog.csdn.net/qq7342272/article/details/8175405(关于执行与撤销的具体实例)

     

  • 相关阅读:
    C++ Vector
    难点目录
    学习图片展
    使用Github总结
    更改git bash默认的路径
    kubernetes dashboard 搭建参考
    vCenter 6.5 Appliance安装问题汇总
    转-Linux访问Windows FTP服务器中文乱码
    安装升级libpcap至1.9.0
    kubectl patch
  • 原文地址:https://www.cnblogs.com/draem0507/p/3795249.html
Copyright © 2011-2022 走看看