【重温设计模式】命令模式及其Java示例

news2024/9/27 17:37:49

命令模式的介绍

在我们的编程世界中,设计模式如同一盏指路明灯,它们是前人智慧的结晶,为我们照亮了解决复杂问题的路径。

其中,命令模式是一种行为设计模式,其主要的目标是将操作封装到对象中。这种模式的一个显著特点是,它将请求的发送者和接收者解耦,使得发送者不直接操作接收者。

命令模式的核心在于抽象出一个命令接口,这个接口定义了执行操作的方法。然后,我们可以创建具体的命令类,这些类实现了命令接口,并持有接收者的引用,以便在需要的时候调用接收者的方法。这样,请求者类只需要持有命令对象的引用,而无需知道具体的接收者是谁,也不需要知道如何完成这个操作,只需要调用命令对象的执行方法即可。

在软件开发中,命令模式的应用价值是显而易见的。它能够帮助我们降低系统的耦合度,提高代码的复用性和可维护性。例如,我们在开发一个文本编辑器时,可以使用命令模式来实现撤销、重做等操作。

在接下来的内容中,我们将深入探讨命令模式的结构和组成。

命令模式的结构和组成

在我们刚刚对命令模式的特性进行了初步的探讨之后,接下来,我们将深入探讨命令模式的结构和组成。命令模式主要由四个部分组成:命令接口、具体命令类、请求者类和接收者类。这四个部分的关系可以用一张简单的图来表示,如下所示:

命令接口
+execute()
请求者类
具体命令类1
+execute()
接收者类
具体命令类2
+execute()

首先,我们有一个命令接口,它定义了所有具体命令类需要实现的方法。这些方法通常是与特定操作相关的,例如“执行”、“撤销”等。在Java中,我们可以定义一个名为Command的接口,如下所示:

public interface Command {
    void execute();
}

接下来,我们有具体命令类,它们实现了命令接口,并定义了具体的操作逻辑。例如,我们可以定义一个名为OneMoreCommand的具体命令类,如下所示:

public class OneMoreCommand implements Command {
    private Receiver receiver;

    public OneMoreCommand(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        receiver.doSomething();
    }
}

然后,我们有请求者类,它持有命令对象,并在需要的时候调用命令对象的方法。最后,我们有接收者类,它知道如何执行与命令相关的操作。在OneMoreCommand类中,我们可以看到,它持有一个接收者对象,并在execute方法中调用接收者的方法。

通过这种方式,命令模式将请求的发送者和接收者解耦,使得发送者不需要知道接收者的具体实现,只需要知道如何发送请求即可。这样的设计使得我们的代码更加灵活和易于维护。在接下来的部分,我们将通过一个具体的Java编程实例,来进一步理解和掌握命令模式的使用。

命令模式的Java实例

在上一节中,我们已经详细解析了命令模式的结构,包括命令接口、具体命令类、请求者类、接收者类等组成部分,并通过图解的方式进行了说明。下面,我们将通过一个具体的Java编程实例,展示如何使用命令模式来设计和实现软件功能。

让我们想象一下,我们正在开发一个名为"OneMore"的音乐播放器,我们希望用户可以通过点击按钮来执行播放、暂停、停止等操作。这就是一个典型的命令模式应用场景。

首先,我们定义一个命令接口,名为"Command":

public interface Command {
    void execute();
}

然后,我们为播放、暂停、停止等操作分别定义具体的命令类,它们都实现了"Command"接口:

public class PlayCommand implements Command {
    private OneMore oneMore;
    public PlayCommand(OneMore oneMore) {
        this.oneMore = oneMore;
    }
    @Override
    public void execute() {
        oneMore.play();
    }
}
// 暂停和停止的命令类定义类似,此处省略

接着,我们定义一个请求者类,也就是按钮类,它持有一个命令对象,并在被点击时执行命令:

public class Button {
    private Command command;
    public Button(Command command) {
        this.command = command;
    }
    public void click() {
        command.execute();
    }
}

最后,我们定义了接收者类"OneMore",它是真正执行各种操作的类:

public class OneMore {
    public void play() {
        System.out.println("OneMore is playing music.");
    }
    // 暂停和停止的方法定义类似,此处省略
}

通过以上的设计,我们可以看到,命令模式将请求者和接收者解耦,使得请求者不需要知道接收者的具体实现,只需要调用命令对象的execute()方法即可。这就是命令模式的魅力所在。

接下来,我们将进一步分析命令模式的优缺点及适用场景,帮助读者正确地理解和应用命令模式。

命令模式的优缺点及适用场景

命令模式的优点在于其能够将请求发送者和接收者解耦,使得发送者不需要知道接收者的任何信息,只需要知道如何发送请求即可。同时,由于命令是作为一个独立的对象存在,因此可以方便地进行存储、传递、调用、增加与管理。此外,命令模式还支持撤销操作,增加了软件的灵活性。

然而,命令模式也不是没有缺点。由于每一个命令都是一个具体的类,因此如果命令非常多,可能会导致程序中类的数量大大增加,增加了系统的复杂性。

在实际的软件开发中,命令模式主要适用于以下场景:

  1. 需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
  2. 需要在不同的时间指定请求、将请求排队和执行请求。
  3. 需要支持撤销操作。

总结

我们详细地探讨了命令模式的概念、结构、实现以及优缺点。我们发现,命令模式以其独特的设计,为我们提供了一种有效的方法来解耦请求的发送者和接收者,使得我们的代码更加灵活、可维护和可复用。

然而,正如我们在文章中所讨论的,命令模式并不是万能的。如果命令太多,可能会导致类的数量大大增加,增加了系统的复杂性。因此,在使用命令模式时,我们需要根据实际的需求和场景来进行选择,不能盲目地追求设计模式,而忽视了代码的简洁和易读性。

在编程世界中,设计模式只是我们解决问题的工具之一,而不是目的。我们的目标应该是写出高质量、易读、易维护的代码,而不是追求使用尽可能多的设计模式。毕竟,编程是一种艺术,而不仅仅是一种科学。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1486252.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于springboot+vue的图书电子商务网站

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战,欢迎高校老师\讲师\同行交流合作 ​主要内容:毕业设计(Javaweb项目|小程序|Pyt…

数据修改

Oracle 目录 数据修改 将员工编号的 7369 的员工工资修改为 810,佣金改为 100 将工资最低的员工工资修改为公司的平均工资 将所有在 1981 年雇佣的员工的雇佣日期修改为今天,工资增长 20% 数据的更新操作 Oracle从入门到总裁:https://blog.csdn.n…

学习人工智能的方法及方向!

目录 一、第一部分:了解人工智能 二、人工智能学习路线图 三、职业规划 四、未来展望 五、总结 在这个信息爆炸的时代,想要系统性地学习人工智能(AI)并找到对应方向的工作,你需要一个明确的学习路径和职业规划。本…

【latex】\IEEEpubid版权声明与正文内容重叠

问题描述 撰写IEEE Trans论文时,出现版权声明文字\IEEEpubid与正文内容重叠的问题: 原因分析: 在使用模板时,不小心将以下命令删除了: \IEEEpubidadjcol 解决方案: 在需要换页的位置附近添加以上命令&…

投影和定义投影的区别

Arcmap中关于投影的工具有四个,分别是定义投影、投影、投影栅格、批量投影。这四个工具既有相同之处也有不同之处,下面我将一一介绍。 ①定义投影:Arcmap中关于定义投影工具是这样描述的:“所有地理数据集均具有一个用于显示、测…

【LeetCode题解】2859. 计算 K 置位下标对应元素的和+938. 二叉搜索树的范围和+1028. 从先序遍历还原二叉树(三种方法:栈+递归+集合)

文章目录 [2859. 计算 K 置位下标对应元素的和](https://leetcode.cn/problems/sum-of-values-at-indices-with-k-set-bits/)思路: [938. 二叉搜索树的范围和](https://leetcode.cn/problems/range-sum-of-bst/)思路:写法一:在中间累加写法二…

从零开始学习Netty - 学习笔记 -Netty入门【半包,黏包】

Netty进阶 1.黏包半包 1.1.黏包 服务端代码 public class HelloWorldServer {private static final Logger logger LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());public static void main(String[] args) {NioEventLoopGroup bossGroup new NioEventL…

Linux多线程控制:深入理解与应用(万字详解!)

🎬慕斯主页:修仙—别有洞天 ♈️今日夜电波:どうして (feat. 野田愛実) 0:44━━━━━━️💟──────── 3:01 🔄 ◀️ ⏸ ▶️ …

基于redis实现【最热搜索】和【最近搜索】功能

目录 一、前言二、分析问题三、针对两个问题,使用redis怎么解决问题?1、字符串String2、列表List3、字典Hash4、集合Set5、有序集合ZSet6、需要解决的五大问题 四、编写代码1.pom依赖2.application.yml配置3.Product商品实体4.用户最近搜索信息5.redis辅…

C-V2X系列:C-V2X芯片及模组整理总结

C-V2X、车路协同、车联网、智能网联车学习 C-V2X芯片及模组整理总结

Typora旧版链接(Win+Mac+Linux版)

记得点赞本文!!! 链接:https://pan.baidu.com/s/1IckUvQUBzQkfHNHXla0zkA?pwd8888 提取码:8888 –来自百度网盘超级会员V7的分享

2.模拟问题——4.日期问题

日期问题难度并不大,但是代码量非常大,需要较高的熟练度,因此需要着重练习,主要涉及数组和循环两个方面的知识点,需要熟练的测试代码。 两个经典题型 闰年 闰年满足以下两个条件的任意一个 能够被400整除不能够被1…

Golang Vs Java:为您的下一个项目选择正确的工具

Java 首次出现在 1995 年,由 James Gosling 和 Sun Microsystems 的其他人开发的一种新编程语言。从那时起,Java 已成为世界上最受欢迎和广泛使用的编程语言之一。Java 的主要特点包括其面向对象的设计、健壮性、平台独立性、自动内存管理以及广泛的内置…

JavaSec 基础之 JNDI 注入

文章目录 JNDI简介JNDI 支持的服务协议JNDI 注入JNDI 复现修复 JNDI 简介 JNDI(Java Naming and Directory Interface)是一个应用程序设计的 API,一种标准的 Java 命名系统接口。JNDI 提供统一的客户端 API,通过不同的访问提供者接口JNDI服务供应接口(…

武器大师——操作符详解(下)

目录 六、单目操作符 七、逗号表达式 八、下标引用以及函数调用 8.1.下标引用 8.2.函数调用 九、结构体 9.1.结构体 9.1.1结构的声明 9.1.2结构体的定义和初始化 9.2.结构成员访问操作符 9.2.1直接访问 9.2.2间接访问 十、操作符的属性 10.1.优先性 10.2.结合性 …

Ubuntu20.04使用XRDP安装原生远程桌面

Ubuntu20.04使用XRDP安装原生远程桌面 1.安装gnome桌面 # 如果没有更新过源缓存,先更新一下 sudo apt update# 安装gnome桌面 # 可选参数 --no-install-recommends,不安装推荐组件,减少安装时间和空间占用 sudo apt install ubuntu-desktop…

2.2_5 调度算法

文章目录 2.2_5 调度算法一、适用于早期的批处理系统(一)先来先服务(FCFS,First Come First Serve)(二)短作业优先(SJF,Shortest Job First)(三&a…

力扣706:设计哈希映射

题目: 不使用任何内建的哈希表库设计一个哈希映射(HashMap)。 实现 MyHashMap 类: MyHashMap() 用空映射初始化对象void put(int key, int value) 向 HashMap 插入一个键值对 (key, value) 。如果 key 已经存在于映射中&#x…

设计模式学习笔记 - 设计原则 - 8.迪米特法则(LOD)

前言 迪米特法则,是一个非常实用的原则。利用这个原则,可以帮我们实现代码的 “高内聚、松耦合”。 围绕下面几个问题,来学习迪米特原则。 什么是 “高内聚、松耦合”?如何利用迪米特法则来实现 高内聚、松耦合?哪些…

【python debug】python常见编译问题解决方法_2

序言 记录python使用过程中碰到的一些问题及其解决方法上一篇:python常见编译问题解决方法_1 1. PermissionError: [Errno 13] Permission denied: ‘/lostfound’ 修改前: 修改后(解决): 此外,可能文件夹…