设计模式之命令模式

文章目录

  • 一、介绍
  • 二、命令模式中的角色
  • 三、案例
    • [1. 命令的抽象接口`Command`](#1. 命令的抽象接口Command)
    • [2. 进攻`AttackCommand`](#2. 进攻AttackCommand)
    • [3. 意大利炮`cannonCommand`](#3. 意大利炮cannonCommand)
    • [4. 开炮`FireCommand`](#4. 开炮FireCommand)
    • [5. 李云龙`LiYunLong`](#5. 李云龙LiYunLong)
    • [6. 运行案例](#6. 运行案例)
  • 四、优缺点

一、介绍

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

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

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

二、命令模式中的角色

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

  • 抽象命令接口Command

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

    java 复制代码
    public interface Command {
    
        void execute();
    }
  • 命令接口实现类XXXCommand

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

    java 复制代码
    public class XXXCommand implements Command{
    
        @Override
        public void execute() {
            System.out.println("执行XXX命令对应的逻辑...");
        }
    }
  • 调用命令的客户端类CommandClient

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

    java 复制代码
    public class CommandClient {
    
        public static void main(String[] args) {
            XXXCommand command = new XXXCommand();
            command.execute();
        }
    }

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

三、案例

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

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

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

1. 命令的抽象接口Command

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

java 复制代码
public interface Command {

    void execute();
}

2. 进攻AttackCommand

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

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

java 复制代码
public class AttackCommand implements Command{
    @Override
    public void execute() {
        System.out.println("士兵进行冲锋进攻。。。");
    }
}

3. 意大利炮cannonCommand

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

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

java 复制代码
public class CannonCommand implements Command{
    @Override
    public void execute() {
        System.out.println("二营长将意大利炮拉出来了。。。");
    }
}

4. 开炮FireCommand

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

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

java 复制代码
public class FireCommand implements Command{
    @Override
    public void execute() {
        System.out.println("士兵向平安县城城楼开炮。。。");
    }
}

5. 李云龙LiYunLong

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

java 复制代码
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();
    }
}

6. 运行案例

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

四、优缺点

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

优点:

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

缺点:

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

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

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

相关推荐
苏瞳儿2 小时前
java对数据库的增删改查
java·数据库·oracle
zhangjw342 小时前
Java基础语法:变量、数据类型与运算符,从原理到实战
java·开发语言
yaoxin5211235 小时前
384. Java IO API - Java 文件复制工具:Copy 示例完整解析
java·开发语言·python
NotFound4866 小时前
实战指南如何实现Java Web 拦截机制:Filter 与 Interceptor 深度分享
java·开发语言·前端
一 乐7 小时前
医院挂号|基于springboot + vue医院挂号管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·医院挂号管理系统
鱼鳞_7 小时前
Java学习笔记_Day29(异常)
java·笔记·学习
烟锁池塘柳08 小时前
一文讲透 C++ / Java 中方法重载(Overload)与方法重写(Override)在调用时机等方面的区别
java·c++·面向对象
一叶飘零_sweeeet8 小时前
深入拆解 Fork/Join 框架:核心原理、分治模型与参数调优实战
java·并发编程
云烟成雨TD8 小时前
Spring AI Alibaba 1.x 系列【23】短期记忆
java·人工智能·spring
摇滚侠8 小时前
帮我整理一份 IDEA 开发中常用快捷键
java·ide·intellij-idea