命令方法 - Python设计模式
命令方法是将请求封装为对象的行为设计模式,从而允许对具有不同请求的客户端进行参数化以及对请求进行排队或记录。在我们的类比中参数化具有不同请求的其他对象意味着用于打开灯的按钮稍后可以用于打开立体声或打开车库门。它有助于将“对对象的方法调用”提升为完整的对象状态。基本上,它封装了执行操作或触发事件所需的所有信息。
不使用命令方法的问题
想象一下,您正在使用代码编辑器。您当前的任务是在编辑器的工具栏中为各种不同的操作添加新按钮。创建可用于按钮的单个按钮类绝对容易。我们知道编辑器中使用的所有按钮看起来都很相似,那么我们应该怎么做呢?我们是否应该为每个使用按钮的地方创建很多子类?
使用命令方法的解决方案
让我们看一下上述问题的解决方案。将软件分成不同的层总是一个好主意,这有助于轻松编码和调试。命令模式建议对象不应该直接发送这些请求。相反,您应该将所有请求的详细信息(例如被调用的对象、方法的名称和参数列表)提取到一个单独的命令类中,并使用一个触发该请求的方法。
Python3
"""Use built-in abc to implement Abstract classes and methods"""
from abc import ABC, abstractmethod
"""Class Dedicated to Command"""
class Command(ABC):
"""constructor method"""
def __init__(self, receiver):
self.receiver = receiver
"""process method"""
def process(self):
pass
"""Class dedicated to Command Implementation"""
class CommandImplementation(Command):
"""constructor method"""
def __init__(self, receiver):
self.receiver = receiver
"""process method"""
def process(self):
self.receiver.perform_action()
"""Class dedicated to Receiver"""
class Receiver:
"""perform-action method"""
def perform_action(self):
print('Action performed in receiver.')
"""Class dedicated to Invoker"""
class Invoker:
"""command method"""
def command(self, cmd):
self.cmd = cmd
"""execute method"""
def execute(self):
self.cmd.process()
"""main method"""
if __name__ == "__main__":
"""create Receiver object"""
receiver = Receiver()
cmd = CommandImplementation(receiver)
invoker = Invoker()
invoker.command(cmd)
invoker.execute()
输出
Action performed in receiver.
类图
下面是 Command 方法的类图
好处
- 开放/封闭原则:我们可以在不破坏现有客户端代码的情况下将新命令引入应用程序。
- 单一职责原则:这里很容易将调用其他类的操作的类解耦。
- 可实现的UNDO/REDO:借助Command方法可以实现UNDO /REDO的功能。
- 封装:它有助于封装执行动作或事件所需的所有信息。
缺点
- 复杂性增加:随着我们在发送者和接收者之间引入某些层,代码的复杂性增加。
- 类的数量增加:对于每个单独的命令,类的数量都会增加。
- 具体命令:每个单独的命令都是一个具体命令类,它增加了用于实现和维护的类的数量。
适用性
- 实现可逆操作:由于 Command 方法提供了UNDO/REDO操作的功能,我们可以反转操作。
- 参数化:当我们必须使用操作参数化对象时,总是首选使用命令方法。
进一步阅读Java中的命令方法