• 命令模式


    命令模式关注动作本身,通过将动作封装成对象实现调用者和底层实现相分离。调用者只需要简单的下达命令,然后等待命令完成即可,对底层发生了什么完全不知情。关于命令模式一个很直观的例子就是点餐:当我们点餐时,我们只用关心将选好的菜品下单,然后等待送餐即可,我们不关心饭菜是怎么做的,不关心厨师是男是女。

    下面通过一个万能遥控器的例子进一步认识命令模式。

    步入物联网时代,很多家电都可以实现远程控制,我们想看电视,听音乐,打扫房间,只需要按一下遥控器上对应的按键,相应的家电就会自动工作。那么这样的一款遥控器要怎样实现呢?现在的场景是,遥控器上的多个按钮对应多个家电,每个家电都有“开”、“关”两个命令。当然,最重要的地方在于,遥控器还必须要能够方便扩展,以后购置新的家电时,只要加一些按钮就可以了。

    首先定义命令接口,为简单起见,命令接口里面只有execute方法,因为命令就是要被执行的:

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

    遥控器上的每一个按钮都是一个命令,对应不同的电器,所以命令应该有很多种具体类型,假设目前有灯泡、电视、音箱三种家电,电器的定义如下:

     1 // 灯泡
     2 public class Light {
     3   public void on(){
     4     System.out.println("打开电灯。。。");
     5   }
     6 
     7   public void off(){
     8     System.out.println("关闭电灯。。。");
     9   }
    10 }
    11 
    12 // 电视
    13 public class TV {
    14   public void on(){
    15     System.out.println("打开电视。。。");
    16   }
    17 
    18   public void off(){
    19     System.out.println("关闭电视。。。");
    20   }
    21 }
    22 
    23 // 音箱
    24 public class LoudspeakerBox {
    25   public void on(){
    26     System.out.println("打开音箱。。。");
    27   }
    28 
    29   public void off(){
    30     System.out.println("关闭音箱。。。");
    31   }
    32 }

    每种电器都有“开”、“关”两个具体命令,定义如下:

     1 // 开灯命令
     2 public class LightOnCommand implements Command{
     3   Light light;
     4 
     5   public LightOnCommand(Light light){
     6     this.light = light;
     7   }
     8 
     9   @Override
    10   public void execute() {
    11     light.on();
    12   }
    13 }
    14 
    15 // 关灯命令
    16 public class LightOffCommand implements Command{
    17   Light light;
    18 
    19   public LightOffCommand(Light light){
    20     this.light = light;
    21   }
    22 
    23   @Override
    24   public void execute() {
    25     light.off();
    26   }
    27 }
    28 
    29 // 电视和音箱的开关命令与此类型,略去
    30 ...

    现在可以看看遥控器的样子了:

     1 // 遥控器
     2 public class RemoteController {
     3   Command[] onCommands;
     4   Command[] offCommands;
     5 
     6   public RemoteController(int commandSize){
     7     this.onCommands = new Command[commandSize];
     8     this.offCommands = new Command[commandSize];
     9   }
    10 
    11   public void setCommand(int i, Command onCommand, Command offCommand){
    12     onCommands[i] = onCommand;
    13     offCommands[i] = offCommand;
    14   }
    15 
    16   // 按下开按钮
    17   public void onButtonPressed(int i){
    18     onCommands[i].execute();
    19   }
    20 
    21   // 按下关按钮
    22   public void offButtonPressed(int i){
    23     offCommands[i].execute();
    24   }
    25 }

    遥控器针对每一种家电设置了两个开关,按下对应的家电的对应开关,会触发相应的动作。这里只对接了3类家电,实际上完全可以对接任意的家电。现在就需要写个测试类看看遥控器是否正常工作:

     1 public class RemoteControllerTest {
     2   public static void main(String[] args){
     3     Light light = new Light();
     4     TV tv = new TV();
     5     LoudspeakerBox loudspeakerBox = new LoudspeakerBox();
     6     Command lightOn = new LightOnCommand(light);
     7     Command lightOff = new LightOffCommand(light);
     8     Command TVOn = new TVOnCommand(tv);
     9     Command TVOff = new TVOffCommand(tv);
    10     Command LoudspeakerBoxOn = new LoudspeakerBoxOnCommand(loudspeakerBox);
    11     Command LoudspeakerBoxOff = new LoudspeakerBoxOffCommand(loudspeakerBox);
    12 
    13     RemoteController remoteController = new RemoteController(3);
    14     remoteController.setCommand(0, lightOn, lightOff);
    15     remoteController.setCommand(1, TVOn, TVOff);
    16     remoteController.setCommand(2, LoudspeakerBoxOn, LoudspeakerBoxOff);
    17 
    18     remoteController.onButtonPressed(0);
    19     remoteController.offButtonPressed(0);
    20     remoteController.onButtonPressed(1);
    21     remoteController.offButtonPressed(1);
    22     remoteController.onButtonPressed(2);
    23     remoteController.offButtonPressed(2);
    24   }
    25 }

    输出如下:

    打开电灯。。。
    关闭电灯。。。
    打开电视。。。
    关闭电视。。。
    打开音箱。。。
    关闭音箱。。。

    遥控器看起来一起顺利。对以上的代码进行整理,可以得出命令模式的类图如下。

     

    遥控器对应Client,各种家电的开关命令对应ConcreteCommand,Receiver就是家电。

    以上就是命令模式的简单应用,它允许我们将动作封装成命令对象,然后就可以随心所欲地存储、传递和调用它们了。通过命令对象实现调用者和执行者解耦,两者之间通过命令对象间接地进行沟通。

  • 相关阅读:
    Linux驱动之异常处理体系结构简析
    Linux驱动之按键驱动编写(查询方式)
    Linux驱动之LED驱动编写
    Linux驱动之建立一个hello模块
    Linux驱动之内核加载模块过程分析
    制作根文件系统之制作根文件系统步骤详解
    制作根文件系统之Busybox init进程的启动过程分析
    制作根文件系统之内核如何启动init进程
    制作根文件系统之内核挂接文件系统步骤分析
    Linux移植之tag参数列表解析过程分析
  • 原文地址:https://www.cnblogs.com/NaLanZiYi-LinEr/p/11615257.html
Copyright © 2020-2023  润新知