设计模式之命令设计模式

news/2025/3/17 1:53:45/
  • 命令设计模式(Command Pattern)

    • 请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的对象,并把该命令传给相应的对象执行命令,属于行为型模式
    • 命令模式是一种特殊的策略模式,体现的是多个策略执行的问题,而不是选择的问题
  • 应用场景

    • 只要你认为是命令的地方,就可以采用命令模式
    • 日常每个界面、按钮、键盘事件操作都是命令设计模式
  • 角色

    • 抽象命令(Command):需要执行的所有命令都在这里声明

    • 具体命令(ConcreteCommand):定义一个接收者和行为之间的弱耦合,实现execute()方法,负责调用接收者的相应操作,execute()方法通常叫做执行方法

    • 接收者(Receiver):负责具体实施和执行一个请求,干活的角色,命令传递到这里是应该被执行的,实施和执行请求的方法叫做行动方法

    • 请求者(Invoker):负责调用命令对象执行请求,相关的方法叫做行动方法

    • 客户端(Client):创建一个具体命令,ConcreteCommand对象并确定其接收者

      在这里插入图片描述

  • 代码示例,以空调开、关、制冷为例

    /*** 命令执行者:包含具体命令*/
    class ConditionReceiver {public void on() {System.out.println("空调开启了");}public void cool() {System.out.println("空调开始制冷");}public void off() {System.out.println("空调关闭了");}
    }/*** 抽象命令*/
    interface Command {/*** 执行动作*/void execute();
    }/*** 具体命令:开机*/
    class OnCommand implements Command {/*** 对哪个receiver进行命令处理*/private ConditionReceiver receiver;public OnCommand(ConditionReceiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {System.out.println("OnCommand-->execute");receiver.on();}
    }/*** 具体命令:制冷*/
    class CoolCommand implements Command {/*** 对哪个receiver进行命令处理*/private ConditionReceiver receiver;public CoolCommand(ConditionReceiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {System.out.println("CoolCommand-->execute");receiver.cool();}
    }/*** 具体命令:关机*/
    class OffCommand implements Command {/*** 对哪个receiver进行命令处理*/private ConditionReceiver receiver;public OffCommand(ConditionReceiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {System.out.println("OffCommand-->execute");receiver.off();}
    }/*** 请求者*/
    class AppInvoker {private Command onCommand;private Command coolCommand;private Command offCommand;public void setOnCommand(Command onCommand) {this.onCommand = onCommand;}public void setCoolCommand(Command coolCommand) {this.coolCommand = coolCommand;}public void setOffCommand(Command offCommand) {this.offCommand = offCommand;}/*** 开机*/public void on() {onCommand.execute();}/*** 制冷*/public void cool() {coolCommand.execute();}/*** 关机*/public void off() {offCommand.execute();}
    }public class Main {public static void main(String[] args) {// 创建接收者,空调就是接收者ConditionReceiver receiver = new ConditionReceiver();// 创建命令对象,设置命令的接收者OnCommand onCommand = new OnCommand(receiver);CoolCommand coolCommand = new CoolCommand(receiver);OffCommand offCommand = new OffCommand(receiver);// 创建请求者,把命令对象设置进去,app就是请求发起者AppInvoker appInvoker = new AppInvoker();appInvoker.setOnCommand(onCommand);appInvoker.setCoolCommand(coolCommand);appInvoker.setOffCommand(offCommand);appInvoker.on();appInvoker.cool();appInvoker.off();}
    }
    
  • 优点

    • 调用者角色与接收者角色之间没有任何依赖关系,不需要了解到底是哪个接收者执行,降低了系统耦合度
    • 扩展性强,新的命令可以很容易添加到系统中去
  • 缺点

    • 过多的命令模式会导致某些系统有过多的具体命令类

http://www.ppmy.cn/news/1579711.html

相关文章

【漫话机器学习系列】138.召回率(Recall)

深入理解召回率(Recall)—— 分类模型中的关键指标 在机器学习和深度学习的分类任务中,召回率(Recall)是一个重要的评估指标。它用于衡量模型对正类样本的识别能力。本文将深入解析召回率的概念、计算公式、应用场景&…

Qt 6.6.1 中 QPixmap::grabWindow() 的用法与替代方案

一、Qt 6 中的 API 变化 ‌弃用 QPixmap::grabWindow()‌ 在 Qt 6 中,QPixmap::grabWindow() 已被迁移至 QScreen 类,需通过 QScreen::grabWindow() 实现窗口截取‌。 原因: Qt 6 重构了图形模块,QPixmap 的截屏功能被整合到 QSc…

ranger集成starrock报错

org.apache.ranger.plugin.client.HadoopException: initConnection: Unable to connect to StarRocks instance, please provide valid value of field : {jdbc.driverClassName}.. com.mysql.cj.jdbc.Driver. 可能的原因 JDBC 驱动缺失:运行环境中没有安装 MySQL …

MyBatis 如何创建 SqlSession 对象的?

MyBatis 创建 SqlSession 对象的过程主要由 SqlSessionFactory 接口及其实现类来完成。以下是详细步骤: 1. SqlSessionFactory 接口: SqlSessionFactory 是 MyBatis 的核心接口之一,它负责创建 SqlSession 对象。 你可以将 SqlSessionFactory 视为 Sql…

【Qt】qApp简单介绍

1. 介绍 在Qt中,qApp是一个全局指针,它指向当前的QApplication或QGuiApplication对象。这个全局指针在Qt应用程序中非常有用,因为它可以让你在任何地方访问到应用程序对象。 在C中,全局指针是一个可以在程序的任何地方访问的指针…

基于ESP32的桌面小屏幕实战[8]:任务创建

调用任务创建必须要添加下面两个头文件: #include "freertos/FreeRTOS.h" #include "freertos/task.h"还要定义一个静态的任务函数 static void test_task_example(void* arg) {for(;;) {vTaskDelay(1000 / portTICK_PERIOD_MS);printf("…

ChatGPT、DeepSeek、Grok 三者对比:AI 语言模型的博弈与未来

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 1. 引言 随着人工智能技术的飞速发展,AI 语言模型已经成为人机交互、内容创作、代码生成、智能问答等领域的重要工具…

Docker 端口映射的 “隐藏炸弹“ 与安全访问方案

📌 问题描述 在启动 Docker 容器时,使用 -p 3001:3001 端口映射后,发现: 防火墙规则(firewalld、ufw)中看不到 3001 端口,但外部仍然可以访问!iptables 规则被 Docker 自动修改&am…