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

news2024/10/7 10:16:57

什么是命令设计模式?

命令模式(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 = light
    
    def execute(self):
        self.light.turn_on()

# 接收者
class Light:
    def turn_on(self):
        print("Light is ON")

# 调用者/请求者
class RemoteControl:
    def __init__(self):
        self.command = None
    
    def set_command(self, command):
        self.command = command
    
    def 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):
    @abstractmethod
    def execute(self):
        pass

# 具体命令
class LightOnCommand(Command):
    def __init__(self, light):
        self.light = light
    
    def execute(self):
        self.light.turn_on()

class LightOffCommand(Command):
    def __init__(self, light):
        self.light = light
    
    def 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 = None
    
    def set_command(self, command):
        self.command = command
    
    def 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.coloradmin.cn/o/1204451.html

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

相关文章

ros1 基础学习07 - 模拟客户端生成小乌龟服务请求生成小乌龟

模拟客户端生成小乌龟服务请求生成小乌龟 一、话题模型二、创建功能包三 创建客户端Client代码四 配置CMakeLists.txt编译规则:五 测试启动ros 主服务启动小乌龟的服务启动模型客户端服务 一、话题模型 Sever端是海龟仿真器/turtlesim,Client端是待实现…

基于鸡群算法优化概率神经网络PNN的分类预测 - 附代码

基于鸡群算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于鸡群算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于鸡群优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要:针对PNN神经网络的光滑…

SPSS时间序列分析:序列图

前言: 本专栏参考教材为《SPSS22.0从入门到精通》,由于软件版本原因,部分内容有所改变,为适应软件版本的变化,特此创作此专栏便于大家学习。本专栏使用软件为:SPSS25.0 本专栏所有的数据文件请点击此链接下…

【Java 进阶篇】JQuery DOM操作:通用属性操作的绝妙魔法

在前端的舞台上,JQuery犹如一位魔法师,为我们展现了操纵HTML元素的奇妙技巧。而在这个技巧的精妙组成中,通用属性操作是一门绝妙的魔法。在本篇博客中,我们将深入研究JQuery DOM操作中的通用属性操作,揭示这段魔法的神…

基于springboot+vue的学生毕业离校信息网站

项目介绍 该学生毕业离校系统包括管理员、学生和教师。其主要功能包括管理员:首页、个人中心、学生管理、教师管理、离校信息管理、费用结算管理、论文审核管理、管理员管理、留言板管理、系统管理等,前台首页;首页、离校信息、网站公告、留…

海上船舶交通事故VR模拟体验低成本高效率-深圳华锐视点

在海上运输行业,安全事故的防范和应对能力是企业安全教育的重中之重。针对这一问题,海上运输事故VR模拟逃生演练成为了一种创新且高效的教育手段。通过这种演练,企业能够在提升员工安全意识和技能方面获得多方面的帮助。 在VR船舶搜救演练中&…

python 根据经纬度绘制点图 极投影

参考了python cartopy手动导入地图数据绘制底图/python地图上绘制散点图:Downloading:warnings/散点图添加图里标签_python add_feature-CSDN博客 点的颜色按照时间显示 # -*- coding: utf-8 -*- """ Created on Mon Nov 13 11:32:48 2023"&quo…

Python数据容器(序列操作)

序列 1.什么是序列 序列是指:内容连续、有序。可以使用下标索引的一类数据容器 列表、元组、字符串。均可以视为序列 2.序列的常用操作 - 切片 语法:序列[起始下标:结束下标:步长]起始下标表示从何处开始,可以留空,留空视作从…

11.13 牛客刷题8/10

11.13 信号完整性 指针地址 的加减,注意 最后转为16进制

毕业设计项目:基于java+springboot的共享单车信息网站

运行环境 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Ma…

【算法每日一练]-快速幂,倍增,滑动窗口(保姆级教程 篇1) #麦森数 #青蛙跳

之前是考试准备&#xff0c;所以有几天没更新&#xff0c;今天开始继续更新 目录 快速幂模板 题目&#xff1a;麦森数 思路&#xff1a; 题目&#xff1a;青蛙跳 思路&#xff1a; 快速幂模板 #include <bits/stdc.h> #define ll long long using namespa…

【QT】飞机大战

0 项目简介 飞机大战是我们大家所熟知的一款小游戏&#xff0c;本教程就是教大家如何制作一款自己的飞机大战 首先我们看一下效果图 玩家控制一架小飞机&#xff0c;然后自动发射子弹&#xff0c;如果子弹打到了飞下来的敌机&#xff0c;则射杀敌机&#xff0c;并且有爆炸的特…

Java事务详解

一、事务的理解&#xff1a; 1、事务的特性&#xff1a; 1) 原子性&#xff08;atomicity&#xff09;&#xff1a;事务是数据库的逻辑工作单位&#xff0c;而且是必须是原子工作单位&#xff0c;对于其数据修改&#xff0c;要么全部执行&#xff0c;要么全部不执行。 2) 一致性…

SparkSQL之Analyzed LogicalPlan生成过程

经过AstBuilder的处理&#xff0c;得到了Unresolved LogicalPlan。该逻辑算子树中未被解析的有UnresolvedRelation和UnresolvedAttribute两种对象。Analyzer所起到的主要作用就是将这两种节点或表达式解析成有类型的&#xff08;Typed&#xff09;对象。在此过程中&#xff0c;…

AI时代设计工具Motiff亮相世界互联网大会 带来AI在SaaS领域落地应用案例

11月8日&#xff0c;2023年世界互联网大会再次迎来“乌镇时间”&#xff0c;AI时代设计工具Motiff正式亮相。期间&#xff0c;Motiff运营副总裁张昊然出席“新产品新技术”发布会&#xff0c;并发表《Motiff&#xff1a;AI时代设计工具的应用与实践》主题演讲&#xff0c;他表示…

【Linux网络】本地DNS服务器搭建

目录 一、什么是DNS&#xff0c;相关介绍 1、dns是什么&#xff1a; 2、域名的分类&#xff1a; 3、服务器的类型 二、DNS解析的过程 三、DNS的相关配置文件学习 1、本地主机有关的DNS文件学习 2、本地的DNS缓存服务器的文件 3、bind软件的相关配置文件&#xff1a; 4…

C语言 每日一题 牛客网 11.13 Day17

找零 Z国的货币系统包含面值1元、4元、16元、64元共计4种硬币&#xff0c;以及面值1024元的纸币。 现在小Y使用1024元的纸币购买了一件价值为N(0 < N≤1024)的商品&#xff0c;请问最少他会收到多少硬币&#xff1f; 思路 运用if语句进行判断分类 代码实现 int main() {…

Android Glide transform圆形图CircleCrop动态代码描边绘制外框线并rotateImage旋转,Kotlin

Android Glide transform圆形图CircleCrop动态代码描边绘制外框线并rotateImage旋转&#xff0c;Kotlin <?xml version"1.0" encoding"utf-8"?> <FrameLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app&q…

基于SSM的校园预点餐系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

PayPal的CISO谈GenAI如何提高网络安全

在最近一个季度(2023财年第二季度)&#xff0c;PayPal报告收入为73亿美元&#xff0c;同比增长7%&#xff0c;5%的交易增长和37%的增值服务收入增长带来了强劲的季度业绩。截至2022年&#xff0c;PayPal的营收为275亿美元。 在进入PayPal之前&#xff0c;Keren创建了两家网络安…