zoukankan      html  css  js  c++  java
  • 命令模式

    意图:将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化;对请求排队或记录日志,以及支持可撤销的操作
    动机:将”发出请求的对象”和”接收与执行这些请求的对象”分隔开来。
    效果:
    1)、command模式将调用操作的对象和实现该操作的对象解耦
    2)、可以将多个命令装配成一个复合命令,复合命令是Composite模式的一个实例
    3)、增加新的command很容易,无需改变已有的类
    适用性:
    1)、抽象出待执行的动作以参数化某对象
    2)、在不同的时刻指定、排列和执行请求。如请求队列
    3)、支持取消操作
    4)、支持修改日志
    5)、用构建在原语操作上的高层操作构造一个系统。支持事物
    参与者:
    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 package com.test.patten.command;
     2 
     3 /**
     4  * 命令接口
     5  */
     6 public interface Command {
     7     /**
     8      * 执行命令
     9      */
    10     public void execute();
    11     /**
    12      * 撤销命令
    13      */
    14     public void undo();
    15 }
    复制代码
    复制代码
     1 package com.test.patten.command;
     2 
     3 /**
     4  * 命令
     5  */
     6 public class CreateCommand implements Command{
     7     private Receiver receiver;
     8     private String state;
     9     
    10     public CreateCommand(Receiver receiver){
    11         this.receiver = receiver;
    12     }
    13 
    14     @Override
    15     public void execute() {
    16         receiver.action();
    17     }
    18 
    19     @Override
    20     public void undo() {
    21         receiver.unAction();
    22     }
    23     
    24 }
    复制代码
    复制代码
     1 package com.test.patten.command;
     2 
     3 /**
     4  * 命令接收者,命令真正执行人
     5  */
     6 public class Receiver {
     7     public void action(){
     8         System.out.println("执行命令...");
     9     }
    10     
    11     public void unAction(){
    12         System.out.println("撤销命令...");
    13     }
    14 }
    复制代码
    复制代码
     1 package com.test.patten.command;
     2 
     3 public class Invoker {
     4     /**
     5      * 调用者持有命令对象
     6      */
     7     private Command command;
     8 
     9     /**
    10      * 设置命令对象
    11      * @param command
    12      */
    13     public void setCommand(Command command) {
    14         this.command = command;
    15     }
    16     public Command getCommand() {
    17         return command;
    18     }
    19 
    20     /**
    21      * 执行命令
    22      */
    23     public void runCommand(){
    24         command.execute();
    25     }
    26     /**
    27      * 撤销命令
    28      */
    29     public void unDoCommand(){
    30         command.undo();
    31     }
    32 }
    复制代码
    复制代码
     1 package com.test.patten.command;
     2 
     3 public class Client {
     4     public static void main(String[] args){
     5         //创建接受者
     6         Receiver receiver = new Receiver();
     7         //创建命令对象,并设置它的接受者
     8         Command command = new CreateCommand(receiver);
     9         
    10         //创建调用者,将命令对象设置进去
    11         Invoker invoker = new Invoker();
    12         invoker.setCommand(command);
    13         
    14         //这里可以测试一下
    15         invoker.runCommand();
    16         invoker.unDoCommand();
    17     }
    18 }
    复制代码

    常见应用:
    1、工作队列,线程池,日程安排
    2、日志请求(系统恢复)
    要点:
    1、命令模式将发出请求的对象和执行请求的对象解耦
    2、在被解耦的两者之间是通过命令对象进行沟通的。命令对象封装了接收者和一个或一组动作
    3、调用者通过调用命令对象的execute()发出请求,这会使得接收者的动作被调用
    4、调用者可以接受命令当作参数,甚至在运行时动态的进行
    5、命令可以支持撤销,做法是实现一个undo()方法来回到execute()被执行前的状态
    6、宏命令是命令的一种简单的延伸,允许调用多个命令。宏方法也可以支持撤销
    7、实际操作时,很常见使用"聪明"命令对象,也就是直接实现了请求,而不是将工作委托给接受者(弊端?)
    8、命令也可以用来实现日志和事物系统

  • 相关阅读:
    jmeter接口自动化难点系列-jmeter多个线程组接口请求顺序问题
    Oracle 绝对和相对文件编号研究
    Oracle-索引分裂研究
    局域网内git项目克隆
    在CentOS中修改mariadb数据库存储位置
    Mariadb 通过binlog恢复删除(drop table)的数据
    高效边缘流处理方案:使用 OpenYurt 部署和管理 eKuiper
    负载均衡
    电信运营商基于 MQTT 协议 构建千万级 IoT 设备管理平台
    使用 MQTT.fx 接入 EMQ X Cloud
  • 原文地址:https://www.cnblogs.com/liangjq/p/4000623.html
Copyright © 2011-2022 走看看