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

news2025/1/31 0:12:53

一、说明

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

(一) 解决问题

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

(二) 使用场景

  • 需要将操作参数化,以便在不同的时刻执行、排队或记录请求。
  • 需要支持命令的撤销(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博客

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

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

相关文章

P1450 [HAOI2008] 硬币购物 dp 容斥 —— s - c[i]*(d[i]+1)怎么理解

[HAOI2008] 硬币购物 - 洛谷 看了洛谷许多题解,一开始理解不了为什么是 s - c[i]*(d[i]1),为什么要1呢? 其实是dp理解的不好。 这里的意思就是该枚硬币先超过限制,接下来剩下的背包也要填满,4种硬币随便组合的情况数…

Open CASCADE学习|视图

目录 Mainwin.h Mainwin.cpp Mainwin.h ​#pragma once#include <QtWidgets/QMainWindow>#include "Displaywin.h"#include "OCC.h"class Mainwin : public QMainWindow{ Q_OBJECTpublic: Mainwin(QWidget* parent nullptr); ~Mainwin();​pri…

BTC网络 vs ETH网络

设计理念 BTC 网络 比特币是一种数字货币&#xff0c;旨在作为一种去中心化的、不受政府或金融机构控制的电子货币。其主要目标是实现安全的价值传输和储存&#xff0c;比特币的设计强调去中心化和抗审查。 ETH 网络 以太坊是一个智能合约平台&#xff0c;旨在支持分散的应…

深入探究Nginx的使用方法

目录 引言 一、网络状态页 二、Nginx 第三方模块 三、变量 &#xff08;一&#xff09;内置变量 &#xff08;二&#xff09;自定义变量 四、自定义日志 &#xff08;一&#xff09;有关日志的配置信息 &#xff08;二&#xff09;error日志的设置 1.日志的等级 2.自…

RT-Thread 自动初始化

最近的程序设计中用到了RT-Thread中的自动初始化&#xff0c;用起来也非常容易&#xff0c;一个宏就解决了&#xff0c;但是原理是什么呢&#xff1f;下面我们一起来学习&#xff1a; 1.1、一般情况的初始化调用 一般情况下&#xff0c;系统中的初始化会这样做&#xff0c;应该…

如何使用 OpenAI Sora?

Sora - 探索AI视频模型的无限可能 OpenAI 的最新项目名为 Sora&#xff0c;这是一个强大的文本到视频模型&#xff0c;可以根据简单的文本提示生成令人兴奋的视频。这个尖端的人工智能模型允许用户描述一个场景&#xff0c;例如“卡通袋鼠跳迪斯科舞”&#xff0c;Sora将生成与…

交叉编译qt到arm平台

使用pkg-config命令查看xxx包是否存在&#xff1a; pkg-config --print-errors xxx pkg-config的搜索路径可以通过环境变量PKG_CONFIG_PATH指定。需要在运行./configure 之前指定。 ./configure -release -qt-libjpeg -qt-libpng -qt-zlib -qt-pcre -xplatform linux-aarch64-…

主机字节序与网络字节序

大端序和小端序 大端序&#xff08;Big Endian&#xff09;和小端序&#xff08;Little Endian&#xff09;是两种计算机存储数据的方式。 大端序指的是将数据的高位字节存储在内存的低地址处&#xff0c;而将低位字节存储在内存的高地址处。这类似于我们阅读多位数时从左往右…

【HarmonyOS】鸿蒙开发之Stage模型-应用配置文件——第4.2章

Stage模型-应用配置文件 AppScope -> app.json5&#xff1a;应用的全局配置信息entry&#xff1a;OpenHarmony工程模块&#xff0c;编译构建生成一个HAP包 build&#xff1a;用于存放OpenHarmony编译生成的hap包src -> main -> ets&#xff1a;用于存放ArkTS源码src …

kubectl 命令行管理K8S(上)

目录 陈述式资源管理方式 介绍 命令 项目的生命周期 创建 kubectl create命令 发布 kubectl expose命令 更新 kubectl set 回滚 kubectl rollout 删除 kubectl delete 应用发布策略 金丝雀发布 陈述式资源管理方式 介绍 1.kubernetes 集群管理集群资源…

Magento2常见表的作用

1.sales_sequence_profile 更改订单号或者发票号的前缀及最大值

YOLOv6代码解读[01] readme解读

文章目录 模型指标安装训练单GPU多GPU断点续练评估推断部署教程模型指标

Python--界面UI控制,模拟键鼠操作的模块pyautogui(超详细用法)

一、简介 PyAutoGUI是一个Python 第三方库&#xff0c;需要pip install 安装 。它允许我们通过编程方式模拟鼠标和键盘的操作&#xff0c;窗口操作&#xff0c;以及界面的截图匹配。由于它是照搬人的操作&#xff0c;底层没有套牢在Windows系统&#xff0c;所以它可以跨平台。…

韩国突发:将批准比特币ETF

作者&#xff1a;秦晋 韩国两党宣布将批准比特币ETF。比特币也再次成为竞选的宠儿。 4月10日&#xff0c;韩国将迎来每隔4年而进行的一次立法大选。在大选之前&#xff0c;现执政党与反对党都承诺将批准比特币ETF。 我们知道&#xff0c;比特币的主要受众群体以年轻人居多。此前…

Vulnhub靶机网卡启动失败(Raise network interfaces)

完整版见个人博客&#xff1a;xzajyjs.cn 问题 使用一些Linux靶机进行搭建后可能会出现无法搜索到IP的情况&#xff0c;并且会在系统启动时报错&#xff0c;类似下图所示 这个主要是因为vulnhub上的镜像由于搭建环境、版本等问题不适配&#xff0c;网卡没有正确识别导致的&am…

数据结构-关键路径

介绍 在AOV网的基础上&#xff0c;如果用对应边来表示活动持续时间&#xff0c;这种有向图被称为AOE网在AOE网中&#xff0c;入度为0的为源点&#xff0c;出度为0的为汇点&#xff0c;整张网看做是一件事情完成的过程&#xff0c;那么这两个点就是事情的开始和结束。每个活动持…

【程序员怎样才能学好算法】《算法秘籍》给出答案

【文末送书】今天推荐一本优质算法书籍《算法秘籍》&#xff0c;这是一本关于数据结构和算法的书&#xff0c;以Java为描述语言&#xff0c;介绍了计算机编程中常用的数据结构和算法。全书共13章&#xff0c;讲述了常见的数据结构、排序算法、位运算、树、递归、回溯算法、贪心…

消息中间件篇之Kafka-数据清理机制

一、Kafka文件存储机制 Kafka文件存储结构&#xff1a;一个Topic有多个分区。每一个分区都有多个段&#xff0c;每个段都有三个文件。 为什么要分段&#xff1f;1. 删除无用文件方便&#xff0c;提高磁盘利用率。 2. 查找数据便捷。 二、数据清理机制 1.日志的清理策略方案1 根…

《TCP/IP详解 卷一》第7章 防火墙和NAT

7.1 引言 NAT通常改变源IP和源端口&#xff0c;不改变目的IP和目的端口。 7.2 防火墙 常用防火墙&#xff1a; 包过滤防火墙&#xff08;packet-filter firewall&#xff09; 代理防火墙&#xff08;proxy firewall&#xff09; 代理防火墙作用&#xff1a; 1. 通过代理服务…

【递归】【回溯】Leetcode 112. 路径总和 113. 路径总和 II

【递归】【回溯】Leetcode 112. 路径总和 113. 路径总和 II 112. 路径总和解法&#xff1a;递归 有递归就有回溯 记得return正确的返回上去 113. 路径总和 II解法 递归 如果需要搜索整棵二叉树&#xff0c;那么递归函数就不要返回值 如果要搜索其中一条符合条件的路径&#xff…