Python命令模式(Command Pattern)是一种行为型设计模式,它允许将请求或操作封装在对象中,并将其作为参数传递给调用对象,以在不同的环境中执行相同的请求或操作。
功能:
优点:
缺点:
应用场景:
使用方式:
在应用程序开发中的使用:
在实现动态调用功能时,命令模式可以帮助我们实现很好的可扩展性和解耦。以下是一个简单的示例,其中我们使用命令模式来实现动态调用功能。
首先,我们定义一个命令接口,所有的命令都需要实现这个接口。
接下来,我们实现具体的命令,如下所示:
然后,我们需要有一个接收者来执行具体的操作。在这个例子中,我们不需要接收者。
接下来,我们定义一个 Invoker 类,它接收命令并在需要的时候调用它们。在这个例子中,我们使用 Invoker 来动态调用命令。
现在,我们可以使用 Invoker 来执行命令。
from abc import ABC, abstractmethod
# 定义抽象类:命令接口
class Command(ABC):
@abstractmethod
def execute(self):
pass
# 定义实现类:实现具体命令
class test1Command(Command):
def execute(self):
print("test1 command")
class test2Command(Command):
def execute(self):
print("test2 command")
# 定义调用程序类
class Invoker:
def __init__(self):
self.commands = {}
def set_command(self, name, command):
self.commands[name] = command # 存入字典
def execute_command(self, name):
if name in self.commands:
self.commands[name].execute()
else:
print(f"{name} not found!")
# 创建实例
invoker = Invoker()
invoker.set_command("test1", test1Command())
invoker.execute_command("test1")
invoker.set_command("test2", test2Command())
invoker.execute_command("test2")
invoker.execute_command("test")
运行结果:
test1 command
test2 command
test not found!
注意,在这个例子中,我们使用了 Invoker 来管理命令,并且使用命令的名称来动态调用命令。如果我们尝试执行没有添加到 Invoker 中的命令,那么我们就会收到一个错误消息。此外,我们可以使用 Invoker 来添加和删除命令,从而实现更好的可扩展性。
在实现撤销和重做操作的场景中,命令模式可以实现很好的解耦和可扩展性。以下是一个简单的示例,其中我们使用命令模式来实现撤销和重做操作。
首先,我们定义一个命令接口,所有的命令都需要实现这个接口。
接下来,我们实现具体的命令,如下所示:
然后,我们需要有一个接收者来执行具体的操作。在这个例子中,我们定义了一个简单的列表类来实现添加和删除操作。
接下来,我们定义一个 Invoker 类,它接收命令并在需要的时候调用它们。
现在,我们可以使用 Invoker 来执行命令。
from abc import ABC, abstractmethod
# 定义抽象类:命令接口
class Command(ABC):
@abstractmethod
def execute(self):
pass
@abstractmethod
def undo(self):
pass
@abstractmethod
def redo(self):
pass
# 定义实现类:实现具体命令
class AddCommand(Command):
def __init__(self, receiver, value):
self.receiver = receiver
self.value = value
def execute(self):
self.receiver.add(self.value)
def undo(self):
self.receiver.remove(self.value)
def redo(self):
self.execute()
class RemoveCommand(Command):
def __init__(self, receiver, value):
self.receiver = receiver
self.value = value
def execute(self):
self.receiver.remove(self.value)
def undo(self):
self.receiver.add(self.value)
def redo(self):
self.execute()
# 定义接收者
class Receiver():
def __init__(self):
self.data = []
def add(self, item):
self.data.append(item)
print(f"Add item: {item}")
def remove(self, item):
self.data.remove(item)
print(f"Remove item: {item}")
def show(self):
print("Current data: ", self.data)
# 定义调用程序类
class Invoker:
def __init__(self):
self.commands = []
self.index = -1
def set_command(self,command):
self.commands.append(command) # 存入数组
self.index += 1
def execute_command(self):
self.commands[self.index].execute()
def undo_command(self):
if self.index >= 0:
self.commands[self.index].undo()
self.index -= 1
def redo_command(self):
if self.index < len(self.commands) -1:
self.index += 1
self.commands[self.index].redo()
# 创建实例
receiver = Receiver()
invoker = Invoker()
print("1----add")
add_command = AddCommand(receiver, 1)
invoker.set_command(add_command)
invoker.execute_command()
receiver.show()
print("2----add")
add_command = AddCommand(receiver, 2)
invoker.set_command(add_command)
invoker.execute_command()
receiver.show()
print("3----remove")
remove_command = RemoveCommand(receiver, 1)
invoker.set_command(remove_command)
invoker.execute_command()
receiver.show()
print("4----undo")
invoker.undo_command()
receiver.show()
print("5----redo")
invoker.redo_command()
receiver.show()
运行结果:
1----add
Add item: 1
Current data: [1]
2----add
Add item: 2
Current data: [1, 2]
3----remove
Remove item: 1
Current data: [2]
4----undo
Add item: 1
Current data: [2, 1]
5----redo
Remove item: 1
Current data: [2]
注意,在这个例子中,我们使用了 Invoker 来管理命令,并且每次调用 execute_command
方法时,都会执行当前命令。当我们需要执行撤销操作时,我们会调用 undo_command
方法,并将当前命令的索引减去 1。当我们需要执行重做操作时,我们会调用 redo_command
方法,并将当前命令的索引加上 1。如果我们已经达到了命令队列的末尾或开头,那么我们就不会执行任何操作。
在实现日志记录功能时,命令模式可以帮助我们记录每个操作的详细信息,包括操作执行的时间、执行者、执行的结果等。以下是一个简单的示例,其中我们使用命令模式来实现日志记录功能。
首先,我们定义一个命令接口,所有的命令都需要实现这个接口。
每个命令需要实现 execute
方法和 undo
方法。execute
方法实际执行命令逻辑,undo
方法则实现命令的撤销操作。
接下来,我们实现具体的命令,定义了一个具体的命令AddCommand。这个命令需要一个接收者(receiver),它是负责实际执行操作的对象。在这个例子中,使用一个Receiver
类来表示接收者。命令模式还提供了一个 log
方法,用于记录每个操作的详细信息。
使用 Invoker 来执行命令和撤销命令。Invoker可以维护一个命令队列,并同时执行多个命令。
在这个例子中,我们使用了 Invoker 来管理命令队列,并在需要时依次执行它们。我们还实现了一个 undo_commands
方法来撤销最后一个命令,并且在需要时打印当前状态。
from abc import ABC, abstractmethod
# 定义逻辑类
class Command(ABC):
@abstractmethod
def execute(self): # 实现执行命令逻辑
pass
@abstractmethod
def undo(self): # 实现命令撤销
pass
# 定义具体实现类
class AddComand(Command):
def __init__(self, receiver, value):
self.receiver = receiver # 接收者
self.value = value
def execute(self):
result = self.receiver.add(self.value) # 调用Receiver类的add()方法
self.log(result)
def undo(self):
result = self.receiver.remove(self.value) # 调用Receiver类的remove()方法
self.log(result)
def log(self, result):
print(f"added {self.value} to receiver {self.receiver} with result {result}")
class RemoveComand(Command):
def __init__(self, receiver, value):
self.receiver = receiver # 接收者
self.value = value
def execute(self):
result = self.receiver.remove(self.value) # 调用Receiver类的add()方法
self.log(result)
def undo(self):
result = self.receiver.add(self.value) # 调用Receiver类的remove()方法
self.log(result)
def log(self, result):
print(f"Remove {self.value} to receiver {self.receiver} with result {result}")
# 定义接收者
class Receiver():
def __init__(self):
self.items = []
def add(self, item):
self.items.append(item)
return True
def remove(self, item):
if item in self.items:
self.items.remove(item)
return True
return False
def __str__(self): # 定义对象的字符串表示形式
return str(self.items)
# 定义Invoker(调用程序)维护命令队列:执行命令、撤销命令
class Invoker():
def __init__(self):
self.commands = []
self.undo_commands = []
def set_command(self, command):
self.commands.append(command)
def execute_command(self):
for command in self.commands:
command.execute() # 调用具体实现类:执行方法execute()
self.undo_commands.append(command)
self.commands = []
def undo_command(self):
num_commands = len(self.undo_commands)
if num_commands == 0:
return
command = self.undo_commands.pop() # pop()方法删除列表末尾元素,返回列表末尾元素。 pop(0)删除列表第一个元素。
command.undo() # 调用具体实现类:撤销方法undo()
def show(self):
for command in self.undo_commands:
command.show()
# 创建实例
receiver = Receiver()
invoke = Invoker()
add_command = AddComand(receiver, 1)
invoke.set_command(add_command)
# invoke.execute_command()
add_command = AddComand(receiver, 2)
invoke.set_command(add_command)
# invoke.execute_command()
add_command = AddComand(receiver, 3)
invoke.set_command(add_command)
invoke.execute_command()
remove_command = RemoveComand(receiver, 2)
invoke.set_command(remove_command)
invoke.execute_command()
print(receiver)
运行结果:
added 1 to receiver [1] with result True
added 2 to receiver [1, 2] with result True
added 3 to receiver [1, 2, 3] with result True
Remove 2 to receiver [1, 3] with result True
在这个例子中,我们首先添加三个项目到接收者中,然后删除一个项目。我们看到了添加操作的详细信息,包括操作执行的时间、执行者、执行的结果等。
在实际应用中,我们可以将每个命令的详细信息写入日志文件中,以便后续跟踪和调试。同时,我们还可以将日志信息发送到远程服务器上进行中央日志管理。这样可以帮助我们更好地管理和维护系统。