C#中通过Command模式实现Redo/Undo方案
简介
在开发过程中,我们经常需要实现Redo/Undo的功能,在C#中通过使用Command模式可以很容易地实现这个功能。Command模式的本质是把一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化。
实现步骤
第一步 定义命令类
我们首先需要定义一个命令类,它包含对应操作的执行、撤销和重做等功能。以增加、删除为例,可以定义 AddCommand 和 DeleteCommand 类:
public abstract class Command
{
public abstract void Execute();
public abstract void Undo();
public abstract void Redo();
}
public class AddCommand : Command
{
private readonly List<int> _list;
private readonly int _item;
public AddCommand(List<int> list, int item)
{
_list = list;
_item = item;
}
public override void Execute()
{
_list.Add(_item);
}
public override void Undo()
{
_list.Remove(_item);
}
public override void Redo()
{
Execute();
}
}
public class DeleteCommand : Command
{
private readonly List<int> _list;
private readonly int _item;
private int _index;
public DeleteCommand(List<int> list, int item)
{
_list = list;
_item = item;
}
public override void Execute()
{
_index = _list.IndexOf(_item);
_list.Remove(_item);
}
public override void Undo()
{
_list.Insert(_index, _item);
}
public override void Redo()
{
Execute();
}
}
第二步 定义命令栈
命令栈用于存储执行的命令,主要用于实现Redo/Undo的功能。可以定义一个 CommandStack 类来实现:
public class CommandStack
{
private readonly Stack<Command> _commandStack = new Stack<Command>();
private readonly Stack<Command> _redoStack = new Stack<Command>();
public void Execute(Command command)
{
command.Execute();
_commandStack.Push(command);
_redoStack.Clear();
}
public void Undo()
{
if (_commandStack.Count <= 0) return;
var command = _commandStack.Pop();
command.Undo();
_redoStack.Push(command);
}
public void Redo()
{
if (_redoStack.Count <= 0) return;
var command = _redoStack.Pop();
command.Redo();
_commandStack.Push(command);
}
}
第三步 使用命令栈
在实际应用中,我们可以使用上述定义的命令类和命令栈类来实现Redo/Undo的功能,例如:
var list = new List<int>();
var commandStack = new CommandStack();
commandStack.Execute(new AddCommand(list, 1));
commandStack.Execute(new AddCommand(list, 2));
commandStack.Execute(new AddCommand(list, 3));
Console.WriteLine(string.Join(",", list)); // 输出"1,2,3"
commandStack.Undo();
Console.WriteLine(string.Join(",", list)); // 输出"1,2"
commandStack.Undo();
Console.WriteLine(string.Join(",", list)); // 输出"1"
commandStack.Redo();
Console.WriteLine(string.Join(",", list)); // 输出"1,2"
commandStack.Execute(new DeleteCommand(list, 1));
Console.WriteLine(string.Join(",", list)); // 输出"2"
commandStack.Undo();
Console.WriteLine(string.Join(",", list)); // 输出"1,2"
commandStack.Redo();
Console.WriteLine(string.Join(",", list)); // 输出"2"
示例说明
上述示例中,我们首先定义了 AddCommand 和 DeleteCommand 两个命令类,并分别实现了对应的 Execute、Undo 和 Redo 方法。
然后,我们定义了一个 CommandStack 类,并在其中实现了 Execute、Undo 和 Redo 方法来管理命令栈,并且在运行这些方法时,将命令对象加入 Stack 中,以此记录命令的执行、撤销和重做。
最后,我们使用上述定义的命令类和命令栈类来实现 Redo/Undo 的功能,具体包括执行 AddCommand 命令向 list 中添加数字、执行 DeleteCommand 命令从 list 中删除数字等操作。同时,我们通过不断执行 Undo 和 Redo 方法来测试命令栈的正常操作,并最终输出命令栈的状态。
除此之外,我们还可以根据实际需要,更改命令类、命令栈等的实现,来满足不同的场景和功能需求。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#中通过Command模式实现Redo/Undo方案 - Python技术站