鱼C论坛

 找回密码
 立即注册
查看: 1923|回复: 0

[学习笔记] 命令模式

[复制链接]
发表于 2019-7-21 15:42:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
命令模式

看一个具体的需求
    1.我们买了一套智能家电,由照明灯,风扇,洗衣机,我们只要在手机上安装app就可以控制
    这些家电工作
    2.这些智能家电来自不同的厂家,我们不想针对每一种就家电都安装一个app。分别控制,我们希望
    只要一个app就可以控制全部智能家电。
    3.要实现一个app就可以控制所有智能家电的需要,则每个智能家电厂家都要提供提供一个统一的接口给app电泳,这时
    就可以考虑使用命令模式。
    4.命令模式可将“动作的请求者”从“动作的执行者"对象中解耦出来
    5.在我们的例子中,动作的请求者是手机app。动作的执行者是每个厂商的一个家电产品


命令模式的基本介绍
    1.命令模式:在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,
    也不知道被请求的操作是哪个
    我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计
    2.命令模式使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活,实现解耦
    3.在命令模式中,会将一个请求封装为一个对象,以便使用不同参数来表示不同的请求(即命令),同时命令模式
    也支持可撤销操作。
    4.通俗易懂的理解,将军发布命令,士兵去执行,其中有几个角色。将军(命令发布者)、士兵(命令的具体执行者)、
    命令(连接将军和士兵)

命令模式的原理类图
    1.Invoker是调用者角色
    2.Command是命令角色,需要执行的所有命令都在这里,可以是接口或者抽象类
    3.Receiver接受者角色,知道如何实施和执行一个请求相关的操作
    4.ConcreteCommand将一个接收者对象与一个动作绑定,调用接收者相应的操作,实现execute

命令模式解决智能生活项目
    1.应用实例要求
        编写程序,使用命令模式,完成前面的智能家电项目
    2.思路分析和图解
    3.代码实现


  1. //创建命令接口
  2. public interface Command{
  3.     //执行操作
  4.     void execute();
  5.     //撤销操作
  6.     void undo();
  7. }

  8. public class LightOnCommand implements Command{
  9.     LightReceiver light ;

  10.     public LightOnCommand(LightReceiver light){
  11.         this.light = light;
  12.     }

  13.     //执行操作
  14.     public void execute(){
  15.         light.on();
  16.     }
  17.     //撤销操作
  18.     public void undo(){
  19.         light.off();

  20.     }
  21. }

  22. public class LightOffCommand implements Command{
  23.     LightReceiver light ;

  24.     public LightOffCommand(LightReceiver light){
  25.         this.light = light;
  26.     }

  27.     //执行操作
  28.     public void execute(){
  29.         light.off();
  30.     }
  31.     //撤销操作
  32.     public void undo(){
  33.         light.on();

  34.     }
  35. }

  36. //没有命令,即空执行:用于初始化每个按钮,当调用空命令时候,对象什么都不做
  37. //其实,这样就hi是一种设计模式,可以省掉对空判断
  38. public class NoCommand implements Command{
  39.     public void execute(){}
  40.     public void undo(){}
  41. }

  42. public class LightReceiver{
  43.     public void on(){
  44.         System.out.println("电灯打开了...");
  45.     }
  46.     public void off(){
  47.         System.out.println("电灯关闭了...");
  48.     }
  49. }

  50. public  class RemoteController{
  51.     //开按钮
  52.     Command[] onCommands;
  53.     Command[] offCommands;

  54.     //执行撤销命令
  55.     Command undoCommand;

  56.     //构造器初始化
  57.     public RemoteController(){
  58.         onCommands = new Command[5];
  59.         offCommands = new Command[5];
  60.         for(int i = 0 ;i < 5 ;i++){
  61.             onCommands[i] = new NoCommand();
  62.             offCommands[i] = new NoCommand();
  63.         }
  64.     }

  65.     //给按钮设置需要的命令
  66.     public void setCommand(int no ,Command onCommand,Command offCommand){
  67.         onCommands[no] = onCommand;
  68.         offCommands[no] = offCommand;
  69.     }

  70.     //按下开按钮
  71.     public void onButtonWasPushed(int no){
  72.         //找到开按钮,并调用对应方法
  73.         onCommands[no].execute();

  74.         //记录这次操作,用于撤销
  75.         undoCommand = onCommands[no];
  76.     }

  77.     //按下关按钮
  78.     public void offButtonWasPushed(int no){
  79.         //找到开按钮,并调用对应方法
  80.         onCommands[no].execute();

  81.         //记录这次操作,用于撤销
  82.         undoCommand = onCommands[no];
  83.     }

  84.     //按下撤销按钮
  85.     public void undoButtonWasPushed(){
  86.         undoCommand.undo();
  87.     }
  88. }

  89. public class Client{
  90.     public static void main(String[]args){
  91.         //使用命令设计模式完成遥控器对电灯操作
  92.         LightReceiver lightReceiver = new LightReceiver();

  93.         Command  oncmd = new LightOnCommand(lightReceiver);
  94.         Command  offcmd = new LightOffCommand(lightReceiver);

  95.         RemoteController remoteController = new RemoteController();
  96.         remoteController.setCommand(0,oncmd,offcmd);
  97.     }
  98. }
复制代码


命令模式在Spring框架JDBCTemplate应用的源代码分析
    1.Spring框架的JDBCTemplate就使用到了命令模式
    2.代码分析

命令模式的注意事项和细节
    1.将发起请求的对象与执行请求的对象解耦,发起请求的对象是调用者,调用者只要调用命令
    对象的execute()方法就可以让接收者工作,而不必知道具体的接收者对象是谁,是如何实现的
    ,命令对象会负责让接受者执行请求的动作,也就是说:请求发起者和请求执行者之间的解耦是
    通过命令对象实现的,命令对象起到了纽带桥梁作用。
    2.容易设计一个命令队列,只要把命令对象放在队列,就可以多线程的执行命令
    3.容易实现对请求的撤销和重做
    4.命令模式不足:可能导致某些系统有过多的具体命令类,增加了系统的复杂度,这点在
    使用的时候要注意
    5.空命令也是一种设计模式,它为我们省去了判空的操作,在上面的实例中,如果没有空命令
    ,我们每按下一个按键都要判空,这给我们编码带来了一定的麻烦。
    6.命令模式经典的应用场景:界面的一个按钮都是一个命令、模拟cmd、订单的撤销/恢复、出发-反馈
    机制
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-7 03:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表