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

- #!/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()