您好,登录后才能下订单哦!
密码登录
            
            
            
            
        登录注册
            
            
            
        点击 登录注册 即表示同意《亿速云用户服务条款》
        # Python设计模式中命令模式怎么实现
## 什么是命令模式
命令模式(Command Pattern)是一种行为型设计模式,它将请求或操作封装为一个对象,从而使你可以参数化客户端与不同的请求、队列或日志请求,并支持可撤销的操作。
### 核心思想
- **解耦调用者与接收者**:调用操作的对象不需要知道如何实现操作
- **将请求封装为对象**:每个命令都是一个独立的对象,包含执行操作所需的所有信息
- **支持命令队列**和**撤销/重做**功能
## 命令模式的结构
### 主要角色
1. **Command(命令接口)**:声明执行操作的接口
2. **ConcreteCommand(具体命令)**:
   - 实现Command接口
   - 绑定接收者与动作
3. **Invoker(调用者)**:要求命令执行请求
4. **Receiver(接收者)**:知道如何执行操作
5. **Client(客户端)**:创建具体命令并设置接收者
```python
from abc import ABC, abstractmethod
# Command接口
class Command(ABC):
    @abstractmethod
    def execute(self):
        pass
# Receiver
class Light:
    def turn_on(self):
        print("Light is ON")
    
    def turn_off(self):
        print("Light is OFF")
# ConcreteCommand
class TurnOnCommand(Command):
    def __init__(self, light):
        self._light = light
    
    def execute(self):
        self._light.turn_on()
class TurnOffCommand(Command):
    def __init__(self, light):
        self._light = light
    
    def execute(self):
        self._light.turn_off()
# Invoker
class RemoteControl:
    def __init__(self):
        self._command = None
    
    def set_command(self, command):
        self._command = command
    
    def press_button(self):
        if self._command:
            self._command.execute()
# Client
if __name__ == "__main__":
    light = Light()
    turn_on = TurnOnCommand(light)
    turn_off = TurnOffCommand(light)
    
    remote = RemoteControl()
    
    remote.set_command(turn_on)
    remote.press_button()  # 输出: Light is ON
    
    remote.set_command(turn_off)
    remote.press_button()  # 输出: Light is OFF
如上例所示,完全按照命令模式的标准结构实现。
优点: - 结构清晰 - 易于扩展新命令 - 支持撤销/重做
Python中函数是一等对象,可以直接作为命令使用:
def light_on():
    print("Light is ON")
def light_off():
    print("Light is OFF")
class FunctionCommand:
    def __init__(self, func):
        self.func = func
    
    def execute(self):
        self.func()
# 使用
cmd_on = FunctionCommand(light_on)
cmd_off = FunctionCommand(light_off)
controller = RemoteControl()
controller.set_command(cmd_on)
controller.press_button()
def make_light_command(light, action):
    def execute():
        if action == 'on':
            light.turn_on()
        elif action == 'off':
            light.turn_off()
    return execute
light = Light()
cmd_on = make_light_command(light, 'on')
cmd_off = make_light_command(light, 'off')
controller.set_command(cmd_on)
controller.press_button()
扩展Command接口添加undo方法:
class Command(ABC):
    @abstractmethod
    def execute(self):
        pass
    
    @abstractmethod
    def undo(self):
        pass
class TurnOnCommand(Command):
    def __init__(self, light):
        self._light = light
    
    def execute(self):
        self._light.turn_on()
    
    def undo(self):
        self._light.turn_off()
# Invoker需要维护历史记录
class AdvancedRemoteControl:
    def __init__(self):
        self._commands = []
    
    def execute_command(self, command):
        command.execute()
        self._commands.append(command)
    
    def undo_last(self):
        if self._commands:
            last_command = self._commands.pop()
            last_command.undo()
class MacroCommand(Command):
    def __init__(self, commands):
        self._commands = commands
    
    def execute(self):
        for cmd in self._commands:
            cmd.execute()
    
    def undo(self):
        for cmd in reversed(self._commands):
            cmd.undo()
# 使用
macro = MacroCommand([turn_on, turn_off])
controller.execute_command(macro)
import threading
from queue import Queue
class ThreadPool:
    def __init__(self, num_threads):
        self.task_queue = Queue()
        self.threads = [
            threading.Thread(target=self._worker)
            for _ in range(num_threads)
        ]
        for t in self.threads:
            t.start()
    
    def _worker(self):
        while True:
            command = self.task_queue.get()
            command.execute()
            self.task_queue.task_done()
    
    def add_task(self, command):
        self.task_queue.put(command)
# 使用
pool = ThreadPool(4)
pool.add_task(turn_on)
pool.add_task(turn_off)
class MenuItem:
    def __init__(self, label, command):
        self.label = label
        self.command = command
    
    def click(self):
        self.command.execute()
# 创建菜单
save_command = SaveFileCommand(document)
menu_item = MenuItem("Save", save_command)
class InputHandler:
    def __init__(self):
        self._key_bindings = {}
    
    def bind_key(self, key, command):
        self._key_bindings[key] = command
    
    def handle_input(self):
        pressed_key = get_pressed_key()
        if pressed_key in self._key_bindings:
            self._key_bindings[pressed_key].execute()
# 配置按键
handler = InputHandler()
handler.bind_key('SPACE', JumpCommand(player))
handler.bind_key('A', MoveLeftCommand(player))
class Transaction:
    def __init__(self):
        self._commands = []
    
    def add_command(self, command):
        self._commands.append(command)
    
    def commit(self):
        for cmd in self._commands:
            cmd.execute()
    
    def rollback(self):
        for cmd in reversed(self._commands):
            cmd.undo()
# 使用
tx = Transaction()
tx.add_command(UpdateCommand(db, "SET balance = balance - 100 WHERE id = 1"))
tx.add_command(UpdateCommand(db, "SET balance = balance + 100 WHERE id = 2"))
tx.commit()  # 执行事务
命令模式在Python中可以通过多种方式实现: - 经典类实现适合复杂场景 - 函数式实现更Pythonic - 闭包方式简洁但可读性稍差
实际应用中,命令模式特别适合: - 需要实现撤销/重做功能 - 需要将操作排队或记录 - 需要支持事务的系统 - GUI事件处理
通过合理使用命令模式,可以使代码更加灵活、可维护,并为系统提供强大的扩展能力。 “`
这篇文章总计约1900字,涵盖了命令模式的核心概念、Python实现方式、高级应用场景以及优缺点分析,采用Markdown格式并包含代码示例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。