Python设计模式详解之14 —— 命令模式

ops/2024/11/30 9:22:31/

命令模式 (Command Pattern) 是一种行为型设计模式,它将请求封装为对象,从而使您可以用不同的请求、队列或日志来参数化其他对象。命令模式还支持撤销操作。

在 Python 中,命令模式通常用来解耦命令的发送者(调用者)和接收者(执行者),使得命令的调用者不需要知道命令是如何执行的。


结构

  1. 命令接口 (Command): 定义执行操作的接口。
  2. 具体命令 (ConcreteCommand): 实现命令接口,定义执行者的操作。
  3. 接收者 (Receiver): 执行具体命令逻辑的对象。
  4. 调用者 (Invoker): 请求命令执行的对象。
  5. 客户端 (Client): 创建具体命令对象并配置调用者。

Python 实现

python">from abc import ABC, abstractmethod# Command 接口
class Command(ABC):@abstractmethoddef execute(self):pass@abstractmethoddef undo(self):pass# Receiver
class Light:def turn_on(self):print("The light is ON")def turn_off(self):print("The light is OFF")# ConcreteCommand
class LightOnCommand(Command):def __init__(self, light: Light):self.light = lightdef execute(self):self.light.turn_on()def undo(self):self.light.turn_off()class LightOffCommand(Command):def __init__(self, light: Light):self.light = lightdef execute(self):self.light.turn_off()def undo(self):self.light.turn_on()# Invoker
class RemoteControl:def __init__(self):self.command = Nonedef set_command(self, command: Command):self.command = commanddef press_button(self):if self.command:self.command.execute()def press_undo(self):if self.command:self.command.undo()# Client
if __name__ == "__main__":# 创建接收者light = Light()# 创建具体命令light_on = LightOnCommand(light)light_off = LightOffCommand(light)# 创建调用者remote = RemoteControl()# 打开灯remote.set_command(light_on)remote.press_button()remote.press_undo()print()# 关闭灯remote.set_command(light_off)remote.press_button()remote.press_undo()

输出结果

The light is ON
The light is OFFThe light is OFF
The light is ON

模式要点

  1. 解耦: 调用者和接收者被解耦,调用者不需要知道具体的接收者和执行逻辑。
  2. 扩展性: 可以轻松添加新命令,而不修改调用者或接收者的代码。
  3. 历史记录: 可以将命令存储起来用于日志记录或撤销功能。

优点

  • 更好地支持开闭原则(OCP)。
  • 提供了对命令的撤销和重做功能的支持。
  • 命令可以被记录、序列化,支持延迟执行。

缺点

  • 增加了类的数量(每个命令对应一个类)。
  • 对于简单的操作,可能显得过于复杂。

适用场景

  1. 需要将一组操作封装成对象。
  2. 希望记录操作历史、支持撤销和重做功能。
  3. 需要参数化某些行为或操作。

通过命令模式,可以更灵活地管理行为的调用和执行!


http://www.ppmy.cn/ops/137890.html

相关文章

鼠标前进后退键改双击,键盘映射(AutoHotkey)

初衷: 1.大部分鼠标为不可自定义按键,可以自定义的又很贵。 鼠标左键是双击是很频类很高的操作,鼠标前进/后退按键个人感觉使用频率很低,因此把鼠标前进/后退改为双击还是很合适的。 2.有些短款的键盘没有Home或End键,…

Vue 3 组件通信教程

Vue 3 组件通信教程 1. Props 父传子 1.1 基础用法 在 Vue 3 中&#xff0c;我们使用 defineProps 来声明组件的 props&#xff1a; <!-- 子组件 ChildComponent.vue --> <script setup> const props defineProps({message: String,count: {type: Number,requ…

激光雷达定位与建图-拟合问题

本篇文章介绍如何在点云中提取线段和平面。 一、平面拟合 1. 问题提出 给定一组由N个点组成的点云 X { x 1 , ⋯ , x n } X \left \{x_{1}, \cdots , x_{n} \right \} X{x1​,⋯,xn​} ,其中每个点取三维欧式坐标 x k x_{k} xk​&#xff0c;寻找一组平面参数n&#xff0c;…

人工智能如何改变你的生活?

在我们所处的这个快节奏的世界里&#xff0c;科技融入日常生活已然成为司空见惯的事&#xff0c;并且切实成为了我们生活的一部分。在这场科技变革中&#xff0c;最具变革性的角色之一便是人工智能&#xff08;AI&#xff09;。从我们清晨醒来直至夜晚入睡&#xff0c;人工智能…

原型模式

功能&#xff1a;复制一个运行时的对象&#xff0c;包括对象各个成员当前的值。并且能够通过父类的指针来克隆出子类的对象 主要解决&#xff1a;在运行期建立原型 优点&#xff1a;性能提高、避免了构造函数的约束 步骤&#xff1a; 1、定义抽象原型&#xff0c;声明纯虚接…

C# 可空类型

文章目录 前言一、单问号&#xff08;?&#xff09;二、双问号&#xff08;??&#xff09; 前言 可空类型&#xff08;Nullable&#xff09;是一个极具实用性的特性&#xff0c;它为我们处理那些可能出现未赋值情况的数据提供了便捷且合理的方式。而其中&#xff0c;单问号&…

如何使用 Codegen 加速 React Native 开发?

写在前面 在 React Native 开发中&#xff0c;经常需要编写大量的样板代码&#xff0c;例如组件、屏幕、API 等。这些重复性的工作不仅浪费时间&#xff0c;还容易出错。为了解决这个问题&#xff0c;Facebook 推出了一个名为 Codegen 的工具&#xff0c;它可以根据模板和配置…

海盗王用golang重写的AccountServer功能

自从用golang重写了海盗王的网关gateserver以来&#xff0c;一直想把accountserver也重写了&#xff0c;但是一直没有进行。 趁上次刚写好那个golang版的更新器&#xff0c;还有些熟悉&#xff0c;于是把原来AccountServer的C代码重写读了个大概。它原版的写得太过于复杂&#…