一、定义
在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可以在以后将对象恢复到原先保存的状态。备忘录模式是一种对象行为型模式,其别名为标记(Token)模式。
二、描述
备忘录模式的核心在于备忘录类以及用于管理备忘录的负责人类的设计,包含以下三个角色:
1、Originator(原发器):原发器是一个普通类,它通过创建一个备忘录来存储其当前内部状态,也可以使用备忘录来恢复其内部状态,一般将需要保存内部状态的类设计为原发器。
2、Memento(备忘录):备忘录用于存储原发器的内部状态,根据原发器来决定保存哪些内部状态。备忘录的设计一般可以参考原发器的设计,根据实际需要确定备忘录类中的属性。用户需要注意的是,除了原发器本身与负责人类之外,备忘录对象不能直接供其他类使用,原发器的设计在不同的编程语言中实现机制会有所不同。
3、Caretaker(负责人):负责人又称为管理者,它负责保存备忘录,但是不能对备忘录的内容进行操作或检查。在负责人类中可以存储一个或多个备忘录对象,它只负责存储对象,不能修改对象,也无须知道对象的实现细节。
三、例子
X公司欲开发一款中国象棋App,基于新手友好、及防误触等原因,设计App具有“悔棋”功能,可恢复到前一步
Chessman:原发器
public class Chessman
{
public string Label { get; set; }
public int X { get; set; }
public int Y { get; set; }
public Chessman(string label, int x, int y)
{
Label = label;
X = x;
Y = y;
}
// 保存状态
public ChessmanMemento Save()
{
return new ChessmanMemento(Label, X, Y);
}
// 恢复状态
public void Restore(ChessmanMemento memento)
{
Label = memento.Label;
X = memento.X;
Y = memento.Y;
}
}
ChessmanMemento:备忘录
public class ChessmanMemento
{
public string Label { get; set; }
public int X { get; set; }
public int Y { get; set; }
public ChessmanMemento(string label, int x, int y)
{
Label = label;
X = x;
Y = y;
}
}
MementoCaretaker:负责人
public class MementoCaretaker
{
private IList<ChessmanMemento> mementoList = new List<ChessmanMemento>();
public ChessmanMemento GetMemento(int i)
{
return mementoList[i];
}
public void SetMemento(ChessmanMemento memento)
{
mementoList.Add(memento);
}
}
Program:测试代码
private static int index = -1;
private static MementoCaretaker mementoCaretaker = new MementoCaretaker();
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);
// 下棋
void Play(Chessman chess)
{
// 保存备忘录
mementoCaretaker.SetMemento(chess.Save());
index++;
Console.WriteLine("棋子 {0} 当前位置为 第 {1} 行 第 {2} 列", chess.Label, chess.X, chess.Y);
}
// 悔棋
void Undo(Chessman chess, int i)
{
Console.WriteLine("---------- Sorry,俺悔棋了 ---------");
index--;
// 撤销到上一个备忘录
chess.Restore(mementoCaretaker.GetMemento(i - 1));
Console.WriteLine("棋子 {0} 当前位置为 第 {1} 行 第 {2} 列", chess.Label, chess.X, chess.Y);
}
// 撤销悔棋
void Redo(Chessman chess, int i)
{
Console.WriteLine("---------- Sorry,撤销悔棋 ---------");
index++;
// 恢复到下一个备忘录
chess.Restore(mementoCaretaker.GetMemento(i + 1));
Console.WriteLine("棋子 {0} 当前位置为 第 {1} 行 第 {2} 列", chess.Label, chess.X, chess.Y);
}
Console.ReadLine();
四、总结
1、优点
(1)备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。
(2)备忘录模式实现了对信息的封装,一个备忘录对象是一种原发器对象状态的表示,不会被其他代码所改动。备忘录保存了原发器的状态,采用列表、堆栈等集合来存储备忘录对象,可以实现多次撤销操作。
2、缺点
(1)备忘录模式资源消耗过大,如果需要保存的原发器类的成员变量太多,就不可避免地需要占用大量的存储空间,每保存一次对象状态都需要消耗一定系统资源。
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
暂无评论内容