Python 如何实现 Command(命令)模式?什么是 Command(命令)设计模式?

什么是命令设计模式?

命令模式(Command Design Pattern)是一种行为设计模式,它将请求封装成一个对象,从而允许参数化客户端对象,排队请求,或者对请求进行操作。命令模式支持撤销操作,并通过将操作参数化来实现操作的延迟执行。

在这里插入图片描述

主要角色:

  1. 命令(Command): 声明执行操作的接口。通常包含 execute() 方法。

  2. 具体命令(ConcreteCommand): 实现命令接口,具体定义要执行的操作。

  3. 调用者/请求者(Invoker): 要求命令执行请求的对象。

  4. 接收者(Receiver): 知道如何执行一个请求的对象。

  5. 客户端(Client): 创建具体命令对象,并设置其接收者。

工作流程:

  1. 客户端创建一个具体命令对象,并设置其接收者。

  2. 客户端将命令对象传递给调用者/请求者。

  3. 调用者调用命令的 execute() 方法。

  4. 具体命令对象调用接收者的方法执行实际操作。

优点:

  • 松散耦合: 请求者和接收者解耦,请求者无需知道接收者的具体实现。

  • 可扩展性: 可以轻松添加新的命令和接收者,无需修改现有代码。

  • 支持撤销和恢复: 可以轻松实现命令的撤销和恢复操作。

  • 命令队列: 可以将命令存储在队列中,实现命令的排队执行。

Python实现命令模式示例代码(一):

以下是一个简单的命令模式的示例,假设有一个遥控器(Invoker)和灯(Receiver):

# 命令接口
class Command:def execute(self):pass# 具体命令
class LightOnCommand(Command):def __init__(self, light):self.light = lightdef execute(self):self.light.turn_on()# 接收者
class Light:def turn_on(self):print("Light is ON")# 调用者/请求者
class RemoteControl:def __init__(self):self.command = Nonedef set_command(self, command):self.command = commanddef press_button(self):self.command.execute()# 客户端
light = Light()
light_on = LightOnCommand(light)remote = RemoteControl()
remote.set_command(light_on)
remote.press_button()

在这个例子中,LightOnCommand 是一个具体的命令,它将操作(turn_on)封装成一个命令对象。RemoteControl 是调用者,它接收一个命令并在按下按钮时执行该命令。

Python实现命令模式实例代码(二)

在 Python 中,你可以通过定义接口、具体命令类、接收者类以及调用者类来实现命令模式。以下是一个简单的示例:

from abc import ABC, abstractmethod# 命令接口
class Command(ABC):@abstractmethoddef execute(self):pass# 具体命令
class LightOnCommand(Command):def __init__(self, light):self.light = lightdef execute(self):self.light.turn_on()class LightOffCommand(Command):def __init__(self, light):self.light = lightdef execute(self):self.light.turn_off()# 接收者
class Light:def turn_on(self):print("Light is ON")def turn_off(self):print("Light is OFF")# 调用者/请求者
class RemoteControl:def __init__(self):self.command = Nonedef set_command(self, command):self.command = commanddef press_button(self):self.command.execute()# 客户端
light = Light()
light_on = LightOnCommand(light)
light_off = LightOffCommand(light)remote = RemoteControl()# 设置并执行打开灯的命令
remote.set_command(light_on)
remote.press_button()# 设置并执行关闭灯的命令
remote.set_command(light_off)
remote.press_button()

在这个例子中,Command 是命令的抽象接口,LightOnCommandLightOffCommand 是具体的命令类,分别用于打开和关闭灯。Light 是接收者类,它包含了实际执行操作的方法。RemoteControl 是调用者类,它接收一个命令并在按下按钮时执行该命令。

这个例子演示了命令模式的核心思想:将请求封装成对象,以便参数化客户端对象、排队请求、或者记录请求日志,并支持可撤销的操作。


使用Command命令模式有什么要注意的?

在使用 Command 命令模式时,有一些注意事项和最佳实践,以确保模式的有效实现和易维护的代码:

  1. 接口设计: 定义清晰简洁的命令接口,确保所有具体命令都实现了这个接口。这有助于保持一致性,使得新的命令可以轻松地添加到系统中。

  2. 单一职责原则: 每个具体命令应该只负责一个具体的操作。这有助于保持代码的可读性和可维护性。

  3. 撤销操作: 如果系统需要支持命令的撤销操作,确保命令对象能够保存执行前的状态,并提供一个撤销操作的接口。这需要在设计时考虑。

  4. 命令参数化: 如果命令需要接收参数,确保参数化得当。这可以通过在命令的构造函数中传递参数,或者通过定义命令的执行方法来传递参数。

  5. 调用者与接收者的关系: 确保调用者和接收者之间的关系清晰。调用者不需要知道接收者的具体实现,而是通过命令对象与接收者交互。

  6. 异常处理: 在执行命令时,考虑可能发生的异常情况。确保能够适当地处理异常,提供有意义的错误信息。

  7. 命令的生命周期: 考虑命令对象的生命周期。命令是否需要一直存在,还是可以在执行后被销毁?这有助于优化资源管理。

  8. 命令队列: 如果系统需要支持命令队列,确保命令队列的管理和执行是线程安全的。

  9. 测试: 对命令模式进行适当的单元测试。确保每个具体命令以及整个命令模式的行为都符合预期。

  10. 可扩展性: 考虑系统的可扩展性。命令模式支持方便地添加新的命令,确保设计能够容易地适应变化。

遵循这些最佳实践可以帮助确保 Command 命令模式在系统中的有效应用,并提高代码的可读性和可维护性。


感谢阅读本文!希望通过这篇介绍,让你对命令模式有了更深入的理解,并能在实际的软件设计中灵活运用这一设计模式。

如果您对软件设计模式、编程技术以及其他相关主题感兴趣,欢迎关注、收藏、点赞本文,还有更多精彩的文章等着你。Thanks♪(・ω・)ノ

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringCache(Redis)

一、springcache是什么 springcache是spring的缓存框架,利用了AOP,实现了基于注解的缓存功能,并且进行了合理的抽象,业务代码不用关心底层是使用了什么缓存框架,只需要简单地加一个注解,就能实现缓存功能了…

Clickhouse学习笔记(11)—— 数据一致性

使用合并树引擎时,无论是ReplacingMergeTree还是SummingMergeTree,都只能保证数据的最终一致性,因为数据的去重、聚合等操作会在数据合并的期间进行,而合并会在后台以一个不确定的时间进行,因此无法预先计划&#xff1…

Python实现WOA智能鲸鱼优化算法优化循环神经网络分类模型(LSTM分类算法)项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 鲸鱼优化算法 (whale optimization algorithm,WOA)是 2016 年由澳大利亚格里菲斯大学的Mirjalili 等提…

永达理简析:利用保险的“财务规划”功能维持退休后生活水平

现代社会环境背景下,“自养自老”已经是一种未来养老趋势,很多人会为自己准备一份长期、比较周全的保障,这样财务规划不仅会分担子女的压力,也让自己有一个长远的保障。在各种财务储蓄工具中,商业保险占据着不可取代的…

基于连续Hopfield神经网络优化——旅行商问题优化计算

大家好,我是带我去滑雪! 利用神经网络解决组合优化问题是神经网络应用的一个重要方面。所谓组合优化问题,就是在给定约束条件下,使目标函数极小(或极大)的变量组合问题。将Hopfield网络应用于求解组合优化问…

基于php js+mysql+laravel技术架构的手术麻醉管理系统源码 手麻系统源码

PHP手术麻醉管理系统源码 手麻系统源码 手术麻醉管理系统定义: 手术麻醉系统主要是由麻醉信息管理和监护设备数据采集系统两个部分组成,主要是将麻醉信息和从监护仪器上采集到的数据以及手术信息进行统计。 手术麻醉系统是指专用于住院患者手术与麻醉…

FRC-EP系列--你的汽车数据一站式管家

FRC-EP系列产品主要面向汽车动力总成测试的客户,主要应用方向为残余总线仿真及网关。本文将详细介绍FRC-EP的产品特性和应用场景。 应用场景: 汽车电子生成研发过程中,需要对汽车各个控制器进行仿真测试,典型的测试对象有&#…

5. HTML常用标签

5.1 标签语义 学习标签是有技巧的&#xff0c;重点是记住每个标签的语义。简单理解就是指标签的含义。即这个标签是用来干嘛的。 根据标签的语义&#xff0c;在合适的地方给一个最为合理的标签。可以让页面结构给清晰。 5.2 标题标签 <h1>-<h6>(重要) HTML提供了…

Opentracing概念介绍——Span

文章首发公众号&#xff1a;海天二路搬砖工 引言 作为分布式跟踪系统的标准化API&#xff0c;OpenTracing提供了一种通用的方式来追踪和分析分布式系统中的请求和操作。 在Opentracing中&#xff0c;Span是基本的跟踪单元&#xff0c;用于描述在分布式系统中的一个操作或事件…

基于K7的PXIPXIe数据处理板(Kintex-7 FMC载板)

基于PXI&PXIe总线架构的高性能数据预处理FMC 载板&#xff0c;板卡具有 1 个 FMC&#xff08;HPC&#xff09;接口&#xff0c;1 个 X8 PCIe 和1个PCI主机接口&#xff1b;板卡采用 Xilinx 的高性能 Kintex-7 系列 FPGA 作为实时处理器&#xff0c;实现 FMC 接口数据的采集…

文本生成高精准3D模型,北京智源AI研究院等出品—3D-GPT

北京智源AI研究院、牛津大学、澳大利亚国立大学联合发布了一项研究—3D-GPT&#xff0c;通过文本问答方式就能创建高精准3D模型。 据悉&#xff0c;3D-GPT使用了大语言模型的多任务推理能力,通过任务调度代理、概念化代理和建模代理三大模块&#xff0c;简化了3D建模的开发流程…

如何用Jmeter对数据库执行压力测试

在我看来压力测试的压测对象可以分为UI&#xff0c;接口及数据库三个部分吧&#xff0c;对界面及接口进行压测还算熟悉&#xff0c; 定位性能瓶颈&#xff0c;对数据库SQL执行压测也是需要做的。工具呢&#xff1f;还是Jmeter 1、将需要用到的链接Oracle的架包放到jmeter中 …

【计算机网络笔记】网络层服务模型——虚电路网络

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

三分钟学完Git版本控制常用指令

基本指令 git clone [url] 克隆远程仓库到本地 git clone https://gitee.com/mayun2023a/mprpc.git2.git checkout -b xxx 切换至新分支xxx&#xff08;相当于复制了remote的仓库到本地的xxx分支上) 3.修改或者添加本地代码&#xff08;部署在硬盘的源文件上&#xff09; 4.g…

php的api接口token简单实现

<?php // 生成 Token function generateToken() {$token bin2hex(random_bytes(16)); // 使用随机字节生成 tokenreturn $token; } // 存储 Token&#xff08;这里使用一个全局变量来模拟存储&#xff09; $tokens []; // 验证 Token function validateToken($token) {gl…

模拟实现string类——【C++】

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; &#x1f354;前言&#xff1a; 我们已经将STL中的string类重要接口全部认识并熟练掌握&#xff0c;为了让我们对string与C类与对象更深层次的了解&#xff0c;我们这篇博客将string类进行模拟实现。 目录 string类的…

【Proteus仿真】【51单片机】多路温度控制系统

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使用按键、LED、蜂鸣器、LCD1602、DS18B20温度传感器、HC05蓝牙模块等。 主要功能&#xff1a; 系统运行后&#xff0c;默认LCD1602显示前4路采集的温…

Zabbix监控SSL证书有效期

一、介绍 由于业务需要&#xff0c;最近通过 Let’s Encrypt 申请了一些 SSL 证书&#xff0c;而证书有效期为 3 个月&#xff0c;需要在证书到期之前 renew。由于域名较多经常忘记 renew&#xff0c;导致证书过期&#xff0c;因此想通过 Zabbix 的方式监控证书的到期时间&…

中国电信终端产业联盟5G Inside行业子联盟正式成立!宏电股份作为副理事单位受邀加入

11月9日&#xff0c;中国电信于广州召开“2023中国电信终端生态合作暨中国电信终端产业联盟&#xff08;以下简称CTTA&#xff09;第十四次会员大会”&#xff0c;联盟成员齐聚现场。作为CTTA大会的一个重要环节&#xff0c;中国电信终端产业联盟5G Inside行业子联盟正式成立&a…

Vue.Draggable 踩坑:add 事件与 change 事件中 newIndex 字段不同之谜

背景 最近在弄自定义表单&#xff0c;需要拖动组件进行表单设计&#xff0c;所以用到了 Vue.Draggable(中文文档)。Vue.Draggable 是一款基于 Sortable.js 实现的 vue 拖拽插件&#xff0c;文档挺简单的&#xff0c;用起来也方便&#xff0c;但没想到接下来给我遇到了灵异事件……