• 设计模式之命令模式


    一、介绍

    命令模式(Command Pattern),属于行为型设计模式。指的是把方法调用封装成命令,然后执行该命令。目的是为了将类中的各个方法抽出来,形成独立的类,且该类只有一个方法execute(),调用该类的execute()方法就等同于调用原类中对应的方法。

    更接地气的说法是,A类中有B、C、D三个方法,使用命令模式,将这三个方法抽出来形成独立的类:BCommondCCommondDCommond,这三个类都实现Command接口中的execute()方法,方法的具体实现与A类中的B、C、D三个方法相同。

    将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。

    二、命令模式中的角色

    在命令模式中,我们需要将一个类中的方法都提取出来,将它们封装成对应的命令类(XXXCommand),通过调用这些命令类的执行方法execute()来运行对应的逻辑,因此我们可以声明一个命令的抽象接口Command,由不同的具体命令实现该抽象接口。因此,命令模式中包含两个角色:抽象命令接口Command、命令接口实现类XXXCommand

    • 抽象命令接口Command

      定义一个命令的基本功能方法execute(),用于执行命令。代码如下所示

      public interface Command {
      
          void execute();
      }
      
      • 1
      • 2
      • 3
      • 4
    • 命令接口实现类XXXCommand

      实现抽象命令接口Command,对接口中的execute()方法进行具体实现。代码如下所示

      public class XXXCommand implements Command{
      
          @Override
          public void execute() {
              System.out.println("执行XXX命令对应的逻辑...");
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    • 调用命令的客户端类CommandClient

      在客户端中,通过对命令对象的声明,进而调用该对象的execute()方法以执行对应的命令。

      public class CommandClient {
      
          public static void main(String[] args) {
              XXXCommand command = new XXXCommand();
              command.execute();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    下面是命令模式的通用UML类图

    在这里插入图片描述

    三、案例

    没办法,一说到命令俺就只能想到打仗,那就不妨以李云龙攻打平安县城为例吧。哈哈哈。

    李云龙作为三八六旅独立团团长,可以向他指挥的士兵下达任何作战命令,比如:进攻(attack)拉意大利炮(cannon)开炮(fire),对于这三个命令来说,李云龙相当于命令模式中的客户端,通过下达这几个命令,他的士兵就会执行相应的命令。

    因此结合案例,我们通过代码对其进行演示。

    1. 命令的抽象接口Command

    每一个命令都需要被执行,因此将其抽象为接口类Command,并声明其执行方法execute()

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

    2. 进攻AttackCommand

    新建进攻命令AttackCommand,并实现命令接口Command定义的execute()方法。

    当李云龙对着战士们说:兄弟们冲啊。此时就下达了进攻命令。

    public class AttackCommand implements Command{
        @Override
        public void execute() {
            System.out.println("士兵进行冲锋进攻。。。");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3. 意大利炮cannonCommand

    与**进攻命令(AttackCommand)**相似,实现命令接口,实现方法逻辑。

    当李云龙对着二营长说:**二营长,你他娘的意大利炮呢?**此时就下达了拿出意大利炮的命令。

    public class CannonCommand implements Command{
        @Override
        public void execute() {
            System.out.println("二营长将意大利炮拉出来了。。。");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4. 开炮FireCommand

    与**进攻命令(AttackCommand)**相似,实现命令接口,实现方法逻辑

    当李云龙对着战士说:开炮~~~,这就是开炮命令,战士则需要向平安县城城楼开炮了。

    public class FireCommand implements Command{
        @Override
        public void execute() {
            System.out.println("士兵向平安县城城楼开炮。。。");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5. 李云龙LiYunLong

    李云龙作为独立团指挥官,负责下达各种作战命令。

    public class LiYunLong {
    
        public static void main(String[] args) {
            System.out.println("李云龙:兄弟们冲啊");
            AttackCommand attackCommand = new AttackCommand();
            attackCommand.execute();
            System.out.println();
    
            System.out.println("李云龙:二营长,你他娘的意大利炮呢?");
            CannonCommand cannonCommand = new CannonCommand();
            cannonCommand.execute();
            System.out.println();
    
            System.out.println("李云龙:开炮~~~");
            FireCommand fireCommand = new FireCommand();
            fireCommand.execute();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    6. 运行案例

    运行以上案例,模拟李云龙下达作战命令后,得到以下输出

    在这里插入图片描述

    四、优缺点

    使用命令模式后,我们可以总结出以下优缺点

    优点:

    • 降低了系统耦合度
    • 新的命令可以很容易添加到系统中去。

    缺点:

    • 导致系统有过多的具体命令类。每一个命令都需要新建一个类。


    纸上得来终觉浅,绝知此事要躬行。

    ————————我是万万岁,我们下期再见————————

  • 相关阅读:
    痞子衡嵌入式:借助i.MXRT10xx系列INIT_VTOR功能可以缩短程序热重启时间
    SpringBoot终幕——日志的输出以及Lombok常用注解
    如何高效操作DOM
    电脑系统重装后如何开启Win11实时辅助字幕
    ROSCon 2023 大会回顾
    解决Flutter启动一直卡在 Running Gradle task ‘assembleDebug‘...
    模糊查询like用法实例(Bee)
    SpringBoot实现AOP详解
    数据结构笔记(王道考研) 第五章:树和二叉树
    机器学习笔记 YOLOv9模型相关论文简读
  • 原文地址:https://blog.csdn.net/qq_36234720/article/details/134015185