设计模式实战:命令模式(Command)

在很多系统中,你会遇到这样的需求:

  • 把”操作”当成对象传递
  • 支持操作的撤销(Undo)
  • 支持操作队列 / 延迟执行
  • 支持日志记录与重放

例如:

  • 编辑器的撤销/重做
  • 任务队列(异步执行)
  • 按钮点击绑定不同行为
  • 审批操作记录

如果直接写函数调用:

light.turn_on()
light.turn_off()

看起来简单,但问题是:

  • 操作无法记录
  • 无法撤销
  • 无法统一调度

这时候就需要 —— 命令模式(Command)


一、命令模式解决什么问题?

一句话:

将请求封装为对象,从而使你可以用不同的请求对客户进行参数化。

关键词:

  • 请求封装
  • 解耦调用者与执行者
  • 支持撤销/重做
  • 支持队列

二、核心角色

命令模式包含四个角色:

1️⃣ Command(命令接口)

定义执行操作的接口。

2️⃣ ConcreteCommand(具体命令)

实现具体操作,绑定接收者。

3️⃣ Receiver(接收者)

真正执行动作的对象。

4️⃣ Invoker(调用者)

触发命令执行。

结构:

Invoker → Command → Receiver

三、一个典型场景:智能家居控制

我们用”控制灯”作为例子。


四、Python 实现命令模式

1️⃣ 接收者(Receiver)

class Light:

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

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

2️⃣ 命令接口

from abc import ABC, abstractmethod

class Command(ABC):

    @abstractmethod
    def execute(self):
        pass

3️⃣ 具体命令

class TurnOnCommand(Command):

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

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


class TurnOffCommand(Command):

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

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

4️⃣ 调用者(Invoker)

class RemoteControl:

    def __init__(self):
        self.command = None

    def set_command(self, command: Command):
        self.command = command

    def press_button(self):
        self.command.execute()

5️⃣ 使用方式

light = Light()

on_command = TurnOnCommand(light)
off_command = TurnOffCommand(light)

remote = RemoteControl()

remote.set_command(on_command)
remote.press_button()

remote.set_command(off_command)
remote.press_button()

输出:

灯打开
灯关闭

五、命令模式的核心价值

命令模式本质是:

把”操作”变成对象。

这样带来的好处:

  • 操作可以存储
  • 操作可以传递
  • 操作可以组合
  • 操作可以撤销

六、实现撤销(Undo)

命令模式一个重要能力:撤销操作。

修改命令接口:

class Command(ABC):

    @abstractmethod
    def execute(self):
        pass

    @abstractmethod
    def undo(self):
        pass






次阅读

扫描下方二维码,关注公众号:程序进阶之路,实时获取更多优质文章推送。


扫码关注

评论