实验16:命令模式
本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:
1、理解命令模式的动机,掌握该模式的结构;
2、能够利用命令模式解决实际问题。
[实验任务一]:多次撤销和重复的命令模式
某系统需要提供一个命令集合(注:可以使用链表,栈等集合对象实现),用于存储一系列命令对象,并通过该命令集合实现多次undo()和redo()操作,可以使用加法运算来模拟实现。
实验要求:
1. 类图:
2. 源代码:
AbstractCommand.py 抽象命令类
from abc import ABC, abstractmethod
class AbstractCommand(ABC):
@abstractmethod
def execute(self, value: int) -> int:
pass
@abstractmethod
def undo(self) -> int:
pass
@abstractmethod
def redo(self) -> int:
pass
Adder.py 接收者类
class Adder:
def __init__(self):
self.num = 0
def add(self, value: int) -> int:
self.num += value
return self.num
AddCommand.py 具体命令类
from AbstractCommand import AbstractCommand
from Adder import Adder
from collections import deque
class AddCommand(AbstractCommand):
def __init__(self):
self.adder = Adder()
self.un_stack = deque() # 返回栈,用来记录所做的每一步操作,用于撤回
self.re_stack = deque() # 重复栈,用来存储返回栈弹出的数据,由于重复
def execute(self, value: int) -> int:
if not self.un_stack:
result = self.adder.add(value)
self.un_stack.append(result)
else:
result = self.un_stack[-1]
result = self.adder.add(value)
self.un_stack.append(result)
self.re_stack.clear() # 清空重做栈
return result
def undo(self) -> int:
if not self.un_stack:
return -1
result = self.un_stack.pop()
self.re_stack.append(result)
return result if self.un_stack else -1
def redo(self) -> int:
if not self.re_stack:
return -1
result = self.re_stack.pop()
self.un_stack.append(result)
return result
CalculatorForm.py 调用者类
from AbstractCommand import AbstractCommand
class CalculatorForm:
def __init__(self):
self.command: AbstractCommand = None
def set_command(self, command: AbstractCommand):
self.command = command
def compute(self, value: int):
if self.command:
self.command.execute(value)
def undo(self):
if self.command:
result = self.command.undo()
if result == -1:
print("缓存中已不存在数据")
else:
print(f"执行成功,运算结果是:{result}")
def redo(self):
if self.command:
result = self.command.redo()
if result == -1:
print("已恢复至最新数据")
else:
print(f"执行成功,运算结果是:{result}")
Client.py 客户端类
from CalculatorForm import CalculatorForm
from AddCommand import AddCommand
def main():
form = CalculatorForm()
command = AddCommand()
form.set_command(command)
# 计算
print("------计算过程------")
form.compute(1)
form.compute(2)
form.compute(3)
form.compute(4)
# 多次撤回
print("------撤回过程------")
form.undo()
form.undo()
form.undo()
form.undo()
form.undo()
# 多次恢复
print("------恢复过程------")
form.redo()
form.redo()
form.redo()
form.redo()
form.redo()
if __name__ == "__main__":
main()