class Program
{
static void Main(string[] args)
{
//1:组装命令和接收者
//创建接收者
OperationApi operation = new Operation();
//创建命令对象,并组装命令和接收者
AddCommand addCmd = new AddCommand(operation, 5);
SubCommand substractCmd = new SubCommand(operation, 3);
//2:把命令设置到持有者,就是计算器里面
Calculator calculator = new Calculator();
calculator.SetAddCommand(addCmd);
calculator.SetSubCommand(substractCmd);
//3:模拟按下按钮,测试一下
calculator.AddPressed();
Console.WriteLine("一次加法运算后的结果为:" + operation.GetResult());
calculator.SubPressed();
Console.WriteLine("一次减法运算后的结果为:" + operation.GetResult());
//测试撤消
calculator.UndoPressed();
Console.WriteLine("撤销一次后的结果为:" + operation.GetResult());
calculator.UndoPressed();
Console.WriteLine("再撤销一次后的结果为:" + operation.GetResult());
//测试恢复
calculator.RedoPressed();
Console.WriteLine("恢复操作一次后的结果为:" + operation.GetResult());
calculator.RedoPressed();
Console.WriteLine("再恢复操作一次后的结果为:" + operation.GetResult());
Console.Read();
}
}
/// <summary>
/// 命令接口,声明执行的操作,支持可撤销操作
/// </summary>
public interface Command
{
/// <summary>
/// 执行命令对应的操作
/// </summary>
void Execute();
/// <summary>
/// 执行撤销命令对应的操作
/// </summary>
void Undo();
}
/// <summary>
/// 具体的加法命令实现对象
/// </summary>
public class AddCommand : Command
{
/// <summary>
/// 持有具体执行计算的对象
/// </summary>
private OperationApi operationApi = null;
/// <summary>
/// 操作的数据,也就是要加上的数据
/// </summary>
private int num;
/// <summary>
/// 构造方法,传入具体执行计算的对象
/// </summary>
/// <param name="operationApi"></param>
/// <param name="num"></param>
public AddCommand(OperationApi operationApi, int num)
{
this.operationApi = operationApi;
this.num = num;
}
public void Execute()
{
////转调接收者去真正执行功能,这个命令是做加法
operationApi.Add(num);
}
public void Undo()
{
//转调接收者去真正执行功能
//命令本身是做加法,那么撤销的时候就是做减法了
operationApi.Sub(num);
}
}
/// <summary>
/// 具体的减法命令实现对象
/// </summary>
public class SubCommand : Command
{
/// <summary>
/// 持有具体执行计算的对象
/// </summary>
private OperationApi operationApi = null;
/// <summary>
/// 操作的数据,也就是要加上的数据
/// </summary>
private int num;
/// <summary>
/// 构造方法,传入具体执行计算的对象
/// </summary>
/// <param name="operationApi"></param>
/// <param name="num"></param>
public SubCommand(OperationApi operationApi, int num)
{
this.operationApi = operationApi;
this.num = num;
}
public void Execute()
{
//转调接收者去真正执行功能,这个命令是做减法
operationApi.Sub(num);
}
public void Undo()
{
//转调接收者去真正执行功能
//命令本身是做减法,那么撤销的时候就是做加法了
operationApi.Add(num);
}
}
/// <summary>
/// 操作运算的接口
/// </summary>
public interface OperationApi
{
/// <summary>
/// 获取计算完成后的结果
/// </summary>
/// <returns></returns>
int GetResult();
/// <summary>
/// 设置计算开始的初始值
/// </summary>
/// <param name="result"></param>
void SetResult(int result);
/// <summary>
/// 执行加法
/// </summary>
/// <param name="num"></param>
void Add(int num);
/// <summary>
/// 执行减法
/// </summary>
/// <param name="num"></param>
void Sub(int num);
}
/// <summary>
/// 运算类,真正实现加减法运算
/// </summary>
public class Operation : OperationApi
{
/// <summary>
/// 记录运算的结果
/// </summary>
private int result;
public int GetResult()
{
return result;
}
/// <summary>
/// 设置值
/// </summary>
/// <param name="result"></param>
public void SetResult(int result)
{
this.result = result;
}
/// <summary>
/// 实现加法功能
/// </summary>
/// <param name="num"></param>
public void Add(int num)
{
result += num;
}
/// <summary>
/// 实现减法功能
/// </summary>
/// <param name="num"></param>
public void Sub(int num)
{
result -= num;
}
}
/// <summary>
/// 计算器类,计算器上有加法按钮、减法按钮,还有撤销和恢复的按钮
/// </summary>
public class Calculator
{
/// <summary>
/// 命令的操作的历史记录,在撤销时候用
/// </summary>
private List<Command> undoCmds = new List<Command>();
/// <summary>
/// 命令被撤销的历史记录,在恢复时候用
/// </summary>
private List<Command> redoCmds = new List<Command>();
/// <summary>
/// 持有执行加法的命令对象
/// </summary>
private Command addCommand = null;
/// <summary>
/// 持有执行减法的命令对象
/// </summary>
private Command subCommand = null;
/// <summary>
/// 设置执行加法的命令对象
/// </summary>
/// <param name="addCommand"></param>
public void SetAddCommand(Command addCommand)
{
this.addCommand = addCommand;
}
/// <summary>
/// 设置执行减法的命令对象
/// </summary>
/// <param name="subCommand"></param>
public void SetSubCommand(Command subCommand)
{
this.subCommand = subCommand;
}
/// <summary>
/// 加法按钮
/// </summary>
public void AddPressed()
{
this.addCommand.Execute();
//把操作记录到历史记录里面
undoCmds.Add(this.addCommand);
}
/// <summary>
/// 减法按钮
/// </summary>
public void SubPressed()
{
this.subCommand.Execute();
//把操作记录到历史记录里面
undoCmds.Add(this.subCommand);
}
/// <summary>
/// 撤销按钮
/// </summary>
public void UndoPressed()
{
if (this.undoCmds.Count > 0)
{
//取出最后一个命令来撤销
Command cmd = this.undoCmds.Last();
cmd.Undo();
//如果还有恢复的功能,那就把这个命令记录到恢复的历史记录里面
this.redoCmds.Add(cmd);
//然后把最后一个命令删除掉,
this.undoCmds.Remove(cmd);
}
else
{
Console.WriteLine("很抱歉,没有可撤销的命令");
}
}
/// <summary>
/// 恢复按钮
/// </summary>
public void RedoPressed()
{
if (this.redoCmds.Count > 0)
{
//取出最后一个命令来重做
Command cmd = this.redoCmds.Last();
cmd.Execute();
//把这个命令记录到可撤销的历史记录里面
this.undoCmds.Add(cmd);
//然后把最后一个命令删除掉
this.redoCmds.Remove(cmd);
}
else
{
Console.WriteLine("很抱歉,没有可恢复的命令");
}
}
}