using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DesignPattern
{
//备忘录模式 标记(Token)模式
//在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可以在以后将对象恢复到原先保存的状态。
internal class MementoPattern
{
public static void Display(Chessman chess)
{
Console.WriteLine("棋子{0}的当前位置为:第{1}行第{2}列", chess.Lable, chess.X, chess.Y);
}
private static int index = -1;//定义一个索引来记录当前状态所在的位置
private static Mementotaker mc = new Mementotaker();
public void main()
{
#region 第一版测试客户端 只能实现单步撤销
//Mementotaker mc = new Mementotaker();
//Chessman chess = new Chessman("车", 1, 1);
//Display(chess);
//mc.SetMemento(chess.Save());//保存状态
//chess.Y = 4;
//Display(chess);
//mc.SetMemento(chess.Save());//保存状态
//Display(chess);
//chess.X = 5;
//Display(chess);
//Console.WriteLine("****悔棋****");
//chess.Restore(mc.GetMemento());//恢复状态
//Display(chess);
//输出
//棋子车的当前位置为:第1行第1列。
//棋子车的当前位置为:第1行第4列。
//棋子车的当前位置为:第1行第4列。
//棋子车的当前位置为:第1行第5列。
//****悔棋****
//棋子车的当前位置为:第1行第4列。
#endregion
#region 第二版测试客户端 可以实现多步撤销和恢复
Chessman chess = new Chessman("车",1,1);
Play(chess);
chess.Y = 4;
Play(chess);
chess.X = 5;
Play(chess);
Undo(chess,index);
Undo(chess, index);
Redo(chess,index);
Redo(chess, index);
//输出
//棋子车的当前位置为:第1行第1列。
//棋子车的当前位置为:第1行第4列。
//棋子车的当前位置为:第5行第4列。
//****悔棋 * ***
//棋子车的当前位置为:第1行第4列。
//****悔棋 * ***
//棋子车的当前位置为:第1行第1列。
//****撤销悔棋 * ***
//棋子车的当前位置为:第1行第4列。
//****撤销悔棋 * ***
//棋子车的当前位置为:第5行第4列。
#endregion
}
//下棋
public static void Play(Chessman chess) {
mc.SetMemento(chess.Save());//保存状态
index++;
Console.WriteLine("棋子{0}的当前位置为:第{1}行第{2}列",chess.Lable,chess.X,chess.Y);
}
//悔棋
public static void Undo(Chessman chess,int i) {
Console.WriteLine("****悔棋****");
index--;
chess.Restore(mc.GetMemento(i - 1));//撤销到上一个备忘录
Console.WriteLine("棋子{0}的当前位置为:第{1}行第{2}列", chess.Lable, chess.X, chess.Y);
}
//撤销悔棋
public static void Redo(Chessman chess, int i) {
Console.WriteLine("****撤销悔棋****");
index++;
chess.Restore(mc.GetMemento(i + 1));//恢复到下一个备忘录
Console.WriteLine("棋子{0}的当前位置为:第{1}行第{2}列", chess.Lable, chess.X, chess.Y);
}
}
/// <summary>
///象棋棋子类 充当原发器 提供棋子状态的保存方法和恢复棋子状态的方法
/// </summary>
class Chessman
{
private string lable;
private int x;
private int y;
public string Lable
{
get { return lable; }
set { lable = value; }
}
public int X
{
get { return x; }
set { x = value; }
}
public int Y
{
get { return y; }
set { y = value; }
}
/// <summary>
/// 棋子构造函数
/// </summary>
/// <param name="lable"></param>
/// <param name="x"></param>
/// <param name="y"></param>
public Chessman(string lable, int x, int y)
{
this.lable = lable;
this.x = x;
this.y = y;
}
//保存状态
internal ChessmanMemento Save()
{
return new ChessmanMemento(this.lable, this.x, this.y);
}
//恢复状态
internal void Restore(ChessmanMemento memento)
{
this.lable = memento.Lable;
this.x = memento.X;
this.y = memento.Y;
}
}
/// <summary>
/// 象棋棋子备忘录类,充当备忘录 棋子状态类
/// </summary>
class ChessmanMemento
{
private string lable;
private int x;
private int y;
internal string Lable
{
get { return lable; }
set { lable = value; }
}
internal int X
{
get { return x; }
set { x = value; }
}
internal int Y
{
get { return y; }
set { y = value; }
}
internal ChessmanMemento(string lable, int x, int y)
{
this.lable = lable;
this.x = x;
this.y = y;
}
}
/// <summary>
/// 棋子备忘录管理类 充当责任人 棋子状态管理类
/// </summary>
public class Mementotaker
{
#region 第一版 只能实现单步撤销
//private ChessmanMemento memento;
//internal ChessmanMemento GetMemento()
//{
// return memento;
//}
//internal void SetMemento(ChessmanMemento memento)
//{
// this.memento = memento;
//}
#endregion
#region 第二版 实现多步撤销和恢复
/// <summary>
/// 定义一个集合来存储多个备忘录
/// </summary>
private ArrayList mementolist = new ArrayList();
/// <summary>
/// 获取当前步骤的旗子状态
/// </summary>
/// <param name="i">步骤序号</param>
/// <returns>ChessmanMemento 棋子状态</returns>
internal ChessmanMemento GetMemento(int i)
{
return (ChessmanMemento)mementolist[i];
}
/// <summary>
/// 记录棋子状态
/// </summary>
/// <param name="memento"></param>
internal void SetMemento(ChessmanMemento memento)
{
mementolist.Add(memento);
}
#endregion
}
}