zoukankan      html  css  js  c++  java
  • 命令模式——HeadFirst设计模式学习笔记

    命令模式:将“请求”封装成对象,以便使用不同的请求、日志、队列等来参数化其他对象。命令模式也支持撤销操作。

    设计原则:

    • 把方法的调用封装起来,调用此对象不需要知道它内部具体是如何运行的,只需要知道包装成型的方法
    • 命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开
    • 将“动作请求者”从“动作执行者”中解耦,即将发出请求的对象和接受并执行请求的对象分离开来。两者通过命令对象沟通
    • 命令模式的关键在于引入了抽象命令接口,且发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联

    特点:

    • 对象只知道通过接口暴露出execute()方法,当此方法调用时,接受者执行具体的动作。对象不知道那个接受者执行了什么动作,只知道操作进行了

    NoCommand对象:execute()方法为空的对象,即不执行任何操作的对象。客户端处理null操作时交给空对象,而无需做if(command != null)操作。

    撤销操作:在管理一组操作对象的对象中可以添加一个上一个操作的对象引用,用于追踪最后调用的命令,并通过命令的undo()方法实现撤销。同样在操作命令对象中也可添加局部变量记录上一个状态以实现undo()方法。

    可使用堆栈记录操作过程中的每一个命令,实现多次撤销

    宏命令:同时执行多个命令,软编码,传入命令数组,动态决定哪些命令

    日志请求:使用命令模式的记录日志,我们可以将上个检查点之后的操作都记录下来,如果系统出现问题,从检查点开始执行命令

    队列请求:把一组命令放到队列(先进先出)中,线程从队列中一个一个删除命令,然后调用它的excecute()方法。

    类图:

    Command:定义命令的接口,声明执行的方法。
    ConcreteCommand:命令接口实现对象,通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。(组合方式)
    Receiver:接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
    Invoker:要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。
    Client:创建具体的命令对象,并且设置命令对象的接收者。真正使用命令的客户端是从Invoker来触发执行。

    举例:

    使用命令模式实现遥控器,遥控器上的不同按钮控制电灯的开关及亮度、天花板风扇的开关及转速等,支持撤销

    1、命令接口:Command

    1 public interface Command { 
    2     public void execute(); 
    3 }

    2、对Receiver(灯)实现开关命令

     1 public class LightOnCommand implements Command { 
     2     Light light; 
     3     public LightOnCommand(Light light) { 
     4         this.light = light; 
     5     } 
     6     public void execute() { 
     7         light.on(); 
     8     } 
     9 }
    10 
    11 public class LightOffCommand implements Command { 
    12     Light light; 
    13     public LightOffCommand(Light light) { 
    14         this.light = light; 
    15     } 
    16     public void execute() { 
    17         light.off(); 
    18     } 
    19 }

    3、实现Invoker控制

     1 public class SimpleRemoteControl { 
     2     Command slot; 
     3     public SimpleRemoteControl() {} 
     4     public void setCommand(Command command) { 
     5         slot = command; 
     6     } 
     7     public void buttonWasPressed() { 
     8         slot.execute(); 
     9     } 
    10 }

    4、Client使用Invoker控制器

    1 public class RemoteControlTest { 
    2     public static void main(String[] args) { 
    3         SimpleRemoteControl remote = new SimpleRemoteControl(); 
    4         Light light = new Light(); 
    5         LightOnCommand lightOn = new LightOnCommand(light); 
    6         remote.setCommand(lightOn); 
    7         remote.buttonWasPressed(); 
    8         } 
    9 }
  • 相关阅读:
    LINUX云计算40个相关问题
    sql
    补肾
    少吃食品
    抗癌食品
    爱情感言
    分布式事务的处理
    前端
    JAVA->Enum
    Sleuth+Zipkin+Log
  • 原文地址:https://www.cnblogs.com/HectorHou/p/5995049.html
Copyright © 2011-2022 走看看