【Python笔记-设计模式】命令模式

一、说明

命令模式是一种行为设计模式,旨在对命令的封装,根据不同的请求将方法参数化、延迟请求执行或将其放入队列中,且能实现可撤销操作。

(一) 解决问题

  • 将请求发送者和接受者解耦,请求发送者只需知道如何发送请求,而无需知道请求是如何被处理、谁来处理请求。
  • 支持请求的排队、记录请求日志、撤销操作等功能。

(二) 使用场景

  • 需要将操作参数化,以便在不同的时刻执行、排队或记录请求。
  • 需要支持命令的撤销(Undo)操作。
  • 需要支持命令的排队执行。

二、结构

  1. 发送者(Sender)负责对请求进行初始化,其中必须包含一个成员变量来存储对于命令对象的引用。发送者触发命令,而不向接收者直接发送请求。注意,发送者并不负责创建命令对象:它通常会通过构造函数从客户端处获得预先生成的命令。
  2. 命令(Command)接口通常仅声明一个执行命令的方法。
  3. 具体命令(ConcreteCommands)会实现各种类型的请求。具体命令自身并不完成工作,而是会将调用委派给一个业务逻辑对象。但为了简化代码,这些类可以进行合并。接收对象执行方法所需的参数可以声明为具体命令的成员变量。你可以将命令对象设为不可变,仅允许通过构造函数对这些成员变量进行初始化。
  4. 接收者(Receiver)类包含部分业务逻辑。几乎任何对象都可以作为接收者。绝大部分命令只处理如何将请求传递到接收者的细节,接收者自己会完成实际的工作。
  5. 客户端(Client)会创建并配置具体命令对象。客户端必须将包括接收者实体在内的所有请求参数传递给命令的构造函数。此后,生成的命令就可以与一个或多个发送者相关联了。

三、伪代码

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
__doc__ = """
命令模式

例:模拟灯光控制场景,使用命令模式实现打开、关闭、撤销操作
"""

from abc import ABC, abstractmethod
from collections import deque


class Command(ABC):
    """抽象命令基类"""

    @abstractmethod
    def execute(self):
        pass

    @abstractmethod
    def undo(self):
        pass


class LightOnCommand(Command):
    """具体命令类(开灯)"""

    def __init__(self, light):
        self.light = light

    def execute(self):
        self.light.turn_on()

    def undo(self):
        self.light.turn_off()


class LightOffCommand(Command):
    """具体命令类(关灯)"""

    def __init__(self, light):
        self.light = light

    def execute(self):
        self.light.turn_off()

    def undo(self):
        self.light.turn_on()


class Light:
    """接收者类"""

    def turn_on(self):
        print(" - 灯光打开")

    def turn_off(self):
        print(" - 灯光关闭")


class RemoteControl:
    """调用者类"""

    def __init__(self):
        self.commands = {}
        self.command_queue = deque()
        self.undo_command = None

    def set_command(self, slot, command):
        self.commands[slot] = command

    def press_button(self, slot):
        if slot in self.commands:
            self.commands[slot].execute()
            self.undo_command = self.commands[slot]

    def undo_last_command(self):
        if self.undo_command:
            self.undo_command.undo()

    def run_commands(self):
        while self.command_queue:
            command = self.command_queue.popleft()
            command.execute()

    def add_to_queue(self, slot):
        if slot in self.commands:
            self.command_queue.append(self.commands[slot])


if __name__ == "__main__":
    """
        执行命令
         - 灯光打开
         - 灯光关闭
        撤销命令
         - 灯光打开
        排队执行命令
         - 灯光关闭
         - 灯光打开
    """
    light = Light()
    remote_control = RemoteControl()
    remote_control.set_command(0, LightOnCommand(light))
    remote_control.set_command(1, LightOffCommand(light))

    print("执行命令")
    remote_control.press_button(0)
    remote_control.press_button(1)

    print("撤销命令")
    remote_control.undo_last_command()

    print("排队执行命令")
    remote_control.add_to_queue(1)
    remote_control.add_to_queue(0)
    remote_control.run_commands()

四、优缺点

优点

  • 降低系统耦合度: 命令模式将请求发送者和接收者解耦,发送者和接收者之间不直接交互,降低了彼此之间的依赖关系,使得系统更加灵活。
  • 容易扩展: 新的命令类可以很容易地添加到系统中,而不影响其他类。
  • 支持撤销和重做: 命令模式可以将命令对象保存起来,以支持撤销和重做操作。
  • 支持命令的排队和记录: 可以将命令对象排队起来,实现对请求的延迟执行或记录日志。

缺点

  • 增加系统复杂度:每个命令都需要一个具体命令类,可能会导致类的数量增加,增加系统的复杂度。

【Python笔记】设计模式-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【力扣hot100】刷题笔记Day14

前言 又是新的一周,快乐的周一,快乐地刷题,今天把链表搞完再干活! 114. 二叉树展开为链表 - 力扣(LeetCode) 前序遍历 class Solution:def flatten(self, root: Optional[TreeNode]) -> None:if not r…

Ubontu更换软件包源库来提高下载速度

对于 apt-get update 运行缓慢的问题,您可以尝试更换软件包源库来提高下载速度。在 Debian 系统中,可以通过编辑 /etc/apt/sources.list 文件来更改软件包源 1、打开 /etc/apt/sources.list 文件:使用文本编辑器(例如 vi、nano 或…

Linux使用Docker部署Traefik容器并实现远程访问管理界面

文章目录 一、Zotero安装教程二、群晖NAS WebDAV设置三、Zotero设置四、使用公网地址同步Zotero文献库五、使用永久固定公网地址同步Zotero文献库 Zotero 是一款全能型 文献管理器,可以 存储、管理和引用文献,不但免费,功能还很强大实用。 ​ Zotero 支…

React Hooks概述及常用的React Hooks介绍

Hook可以让你在不编写class的情况下使用state以及其他React特性 useState ● useState就是一个Hook ● 通过在函数组件里调用它来给组件添加一些内部state,React会在重复渲染时保留这个state 纯函数组件没有状态,useState()用于设置和使用组件的状态属性。语法如下…

StarRocks之监控管理(内含DashBoard模板)

先看下最终效果图 架构 Prometheus 是一个拥有多维度数据模型的、灵活的查询语句的时序数据库。它可以通过 Pull 或 Push 采集被监控系统的监控项,存入自身的时序数据库中。并且通过丰富的多维数据查询语言,满足用户的不同需求。 Grafana 是一个开源的 Metric 分析及可视化系…

springboot-基础-添加model和controller的简单例子+常用注解含义

备份笔记。所有代码都是2019年测试通过的,如有问题请自行搜索解决! 上一篇:springboot-基础-eclipse配置helloword示例 目录 添加model和controller的例子注解开发使用RestController 大坑 添加model和controller的例子 文件结构&#xff1…

Vue.js+SpringBoot开发快递管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 数据中心模块2.2 快递类型模块2.3 快递区域模块2.4 快递货架模块2.5 快递档案模块 三、界面展示3.1 登录注册3.2 快递类型3.3 快递区域3.4 快递货架3.5 快递档案3.6 系统基础模块 四、免责说明 一、摘要 1.1 项目介绍 …

(AtCoder Beginner Contest 340) -- F - S = 1 -- 题解

目录 F - S 1: 题目大意: 思路解析: 代码实现: F - S 1: 题目大意: 思路解析: 这道题需要解决的就是三角形面积怎么用 A、B、X、Y,表示。 exgcd求解大致思路:可看C…

时间序列分析实战(四):Holt-Winters建模及预测

🍉CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一|统计学|干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项,参与研究经费10w、40w级横向 文…

ETH网络中的账户

ETH网络中的账户 Externally owned accounts (EOA) - 外部账户 由用户控制,我们导入助记词创建的账户就属于此类账户。 Contract accounts (smart contracts) - 合约账户 合约账户由以太坊虚拟机执行的代码控制。它也被称为智能合约。合约帐户有相关的代码和数据存…

闪测影像|闪测仪,一键自动批量测量尺寸

在现代化工业中,闪测仪只需一键即可快速批量测量尺寸,为产品尺寸控制和质量管理提供重要保障。 工作原理 机器视觉系统的优势是高精度、重复性的进行运作,并能提供清晰的图像。整个系统由光源、镜头、相机、图像采集卡、图像处理软件等组件…

EfficientSAM | 借助MIM机制,MetaAI让SAM更高效!

本文首发:AIWalker 本文介绍了一种名为EfficientSAM的模型,该模型通过利用遮罩图像预训练来提高图像分割的性能。作者使用了一个名为SAMI的方法,通过将SAM图像编码器的特征作为重建目标,从SAM图像编码器中重建特征,从而…

【XR806开发板试用】XR806简单使用GPIO命令通过继电器远程控制其它开发板

一直关注极术社区,参加过社区的好几个活动,这次在微信群得知有开发板使用活动,果断申请试用。一来想借此学习了解鸿蒙系统,再者学习工作中也确实会用到一些小工具。 之前因工作中因自动化测试需要和远程控制测试板子需要(重启板…

Ansible group模块 该模块主要用于添加或删除组。

目录 创建组验证删除组验证删除一个不存在的组 常用的选项如下: gid  #设置组的GID号 name  #指定组的名称 state  #指定组的状态,默认为创建,设置值为absent为删除 system  #设置值为yes,表示创建为系统组 创建组 ansib…

32. 【Linux教程】Linux 修改用户

前面小节介绍了如何添加 Linux 系统用户、删除 Linux 系统用户,本小节介绍如何修改 Linux 系统用户相关的信息。 1. 用户修改相关命令 下面列举了一些修改用户信息相关的命令: 命令名称功能与作用描述usermod修改用户的字段值,并且可以指定…

同源不同页面之间的通信,SharedWorker使用

同源不同页面之间的通信,SharedWorker使用 描述实现结果 描述 同源不同页面之间的通信,使用SharedWorker,或者使用全局方法通信,这里使用SharedWorker来实现 mdn地址:https://developer.mozilla.org/zh-CN/docs/Web/A…

谷歌Gemini又陷舆论风波;AI虚拟女友恋爱指南;高效提示词必学的两个新语法;LLM超超超长资源清单 | ShowMeAI日报

👀日报&周刊合集 | 🎡生产力工具与行业应用大全 | 🧡 点赞关注评论拜托啦! 🉑 谷歌 Gemini 每次发布大模型必曝「丑闻」:高标准严要求?还是…… https://www.marketwatch.com/story/google-…

机器学习和可视化还能一起这样用?Python教你全搞定

今天这篇推文,我们继续空间数据可视化的最后一个系列-类别插值(categorical-spatial-interpolation) 可视化绘制的推文教程,这期我们使用Python进行绘制,涉及的知识点如下: sklearn.KNeighborsClassifier()机器学习应用 plotnine…

人机界面和三菱PLC之间以太网通信

本文主要描述人机界面WinCC如何与三菱Q系列PLC进行以太网通讯,主要介绍了CPU自带以太网口和扩展以太网模块两种情况以及分别使用TCP、UDP两种协议进行通讯组态步骤及其注意事项。 一、 说明 WinCC从V7.0 SP2版本开始增加了三菱以太网驱动程序,支持和三…

芯课堂 | 上位机快速上手指南

​01.工具准备 1、硬件:SWMDM-QFP100-34SVEA3驱屏板TFT屏800x480(触摸IC-GT911)Jlink; 2、PC端:上位机keil。 02.实验现象 通过屏幕上的按钮控制uart发送。 03.创建文件工程 1、可以通过论坛 https://bbs.synwit.cn 获…