Python设计模式之命令模式原理与用法实例分析
什么是命令模式
命令模式是一种行为型设计模式,它允许将请求封装成一个对象,从而使您可以将不同的请求、队列或日志请求参数化,支持可撤销操作。
在命令模式中,有四个基本角色:
- Command(命令):抽象命令类,声明了执行操作的接口。
- ConcreteCommand(具体命令):将一个接收者对象和一个动作绑定在一起,实现了执行操作的接口。
- Receiver(接收者):知道如何实施与执行一个请求相关的操作。
- Invoker(调用者):调用命令执行请求。
命令模式示例
示例1:智能家居控制器
现在,我们来使用命令模式编写一个智能家居控制器。
定义接收者:具体动作
from abc import ABC, abstractmethod
class Light:
def on(self):
print("The light is on")
def off(self):
print("The light is off")
定义命令接口
class Command(ABC):
@abstractmethod
def execute(self):
pass
定义具体命令
class LightOnCommand(Command):
def __init__(self, light):
self._light = light
def execute(self):
self._light.on()
class LightOffCommand(Command):
def __init__(self, light):
self._light = light
def execute(self):
self._light.off()
实现调用者
class RemoteControl:
def __init__(self):
self._on_commands = []
self._off_commands = []
def set_command(self, command, slot):
if slot < 0 or slot > 1:
return
if isinstance(command, LightOnCommand):
self._on_commands.insert(slot, command)
elif isinstance(command, LightOffCommand):
self._off_commands.insert(slot, command)
def on_button_pressed(self, slot):
self._on_commands[slot].execute()
def off_button_pressed(self, slot):
self._off_commands[slot].execute()
客户端代码
if __name__ == "__main__":
living_room_light = Light()
living_room_light_on = LightOnCommand(living_room_light)
living_room_light_off = LightOffCommand(living_room_light)
remote_control = RemoteControl()
remote_control.set_command(living_room_light_on, 0)
remote_control.set_command(living_room_light_off, 1)
remote_control.on_button_pressed(0)
remote_control.off_button_pressed(1)
remote_control.off_button_pressed(2) # 该操作将不会执行
示例2:财务系统日志记录
现在,我们来看看一个更加实际的例子。假设我们的公司有一个财务系统,我们使用命令模式来记录正常操作和异常操作的日志。
定义接收者
class FinanceSystem:
def pay(self, amount):
print(f"Paid {amount}")
def refund(self, amount):
print(f"Refunded {amount}")
定义命令接口
class FinanceCommand(ABC):
@abstractmethod
def execute(self):
pass
定义具体命令
import logging
class PayCommand(FinanceCommand):
def __init__(self, finance_system, amount):
self._finance_system = finance_system
self._amount = amount
def execute(self):
try:
self._finance_system.pay(self._amount)
logging.info(f"Paid {self._amount}")
except Exception as e:
logging.error(str(e))
class RefundCommand(FinanceCommand):
def __init__(self, finance_system, amount):
self._finance_system = finance_system
self._amount = amount
def execute(self):
try:
self._finance_system.refund(self._amount)
logging.info(f"Refunded {self._amount}")
except Exception as e:
logging.error(str(e))
实现调用者
class FinanceInvoker:
def __init__(self, finance_system):
self._finance_system = finance_system
self._commands = []
def add_command(self, command):
self._commands.append(command)
def execute(self):
for command in self._commands:
command.execute()
客户端代码
if __name__ == "__main__":
finance_system = FinanceSystem()
logging.basicConfig(filename='finance_system.log', level=logging.INFO)
pay_command = PayCommand(finance_system, 100)
refund_command = RefundCommand(finance_system, 50)
finance_invoker = FinanceInvoker(finance_system)
finance_invoker.add_command(pay_command)
finance_invoker.add_command(refund_command)
finance_invoker.execute()
在示例2中,我们使用了Python内置的logging库来记录日志。当捕获到异常时,我们会将错误信息记录下来。通过记录日志,我们可以更好地追踪和debug自己的代码。
结论
在以上的示例中,我们可以看到命令模式的强大。命令模式可以很容易地扩展,而不需要修改现有的代码,只需要添加新的命令即可。它还可以在系统中增加事务性操作,并支持可撤销操作。Python中,命令模式常被用于GUI程序、智能家居等方面的开发。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python设计模式之命令模式原理与用法实例分析 - Python技术站