<table cellspacing="0" cellpadding="0" id="blogContentTable" style="margin:0px; padding:0px; border-collapse:collapse; border-spacing:0px; color:rgb(84,84,84); font-family:Tahoma,'Microsoft Yahei'; font-size:12px; line-height:19px; table-layout:fixed; width:880px; position:relative"><tbody style="margin:0px; padding:0px"><tr style="margin:0px; padding:0px"><td valign="top" style="margin:0px; padding:0px; word-wrap:break-word"><div id="blogContainer" style="margin:0px; padding:0px; position:relative; overflow:hidden; height:2113px"><div id="paperTitleArea" align="center" style="margin:0px; padding:0px"><span id="paperTitle" style="margin:0px; padding:0px; display:block; word-break:break-all"/></div><div id="blogDetailDiv" style="margin:0px; padding:0px; min-height:380px; font-size:14px"><div class="blog_details_20120222" style="margin:0px; padding:0px"><div style="margin:0px; padding:0px"> <span style="margin:0px; padding:0px; font-size:10.5pt; font-family:SimSun"><span style="margin:0px; padding:0px; font-weight:bold">定义:</span>备忘录模式</span><span style="margin:0px; padding:0px; font-size:10.5pt; font-family:Calibri">(MementoPattern)</span><span style="margin:0px; padding:0px; font-size:10.5pt; font-family:SimSun">,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。</span><br/></div><p style="margin:0in; padding-top:0px; padding-bottom:0px; font-family:SimSun; font-size:10.5pt"><span style="margin:0px; padding:0px; font-weight:bold">类型:</span>对象行为型模式。</p><p style="margin:0in; padding-top:0px; padding-bottom:0px; font-family:SimSun; font-size:10.5pt"><span style="margin:0px; padding:0px; font-weight:bold">概述:</span></p><p style="margin:0in; padding-top:0px; padding-bottom:0px; font-size:10.5pt"><span style="margin:0px; padding:0px; font-family:Calibri"> </span><span style="margin:0px; padding:0px; font-family:宋体">备忘录模式使用的范围比较窄,即比较复杂的状态需要恢复到之前的状态。现实更多的情况只有很简单的状态需要恢复,如果用备忘录模式有点大材小用的感觉。就像用大炮打蚊子,起不到什么作用。在《</span><span style="margin:0px; padding:0px; font-family:Calibri">Head First Design Patterns</span><span style="margin:0px; padding:0px; font-family:宋体">》,备忘录模式也被列为不常用的模式之一。</span></p><p style="margin:0in; padding-top:0px; padding-bottom:0px; font-size:10.5pt"><span style="margin:0px; padding:0px; font-family:Calibri"> </span><span style="margin:0px; padding:0px; font-family:宋体">备忘录模式相对比较简单,即把一个有着复杂状态且需要恢复</span><span style="margin:0px; padding:0px; font-family:Calibri">Originator</span><span style="margin:0px; padding:0px; font-family:宋体">的对象中的一些需要被保存的状态再次抽象出来,并提供一些操作接口封装成一个</span><span style="margin:0px; padding:0px; font-family:Calibri">Memento</span><span style="margin:0px; padding:0px; font-family:宋体">类。这样将极大简化</span><span style="margin:0px; padding:0px; font-family:Calibri">Originator</span><span style="margin:0px; padding:0px; font-family:宋体">类的复杂性。</span><span style="margin:0px; padding:0px; font-family:Calibri">Memento</span><span style="margin:0px; padding:0px; font-family:宋体">的接口因为是操作状态的,所以不应该开放给更多的人知道,所以这里又继续封装了一个管理</span><span style="margin:0px; padding:0px; font-family:Calibri">Memento</span><span style="margin:0px; padding:0px; font-family:宋体">类的</span><span style="margin:0px; padding:0px; font-family:Calibri">Caretaker</span><span style="margin:0px; padding:0px; font-family:宋体">类,并提供一些简单对外的接口。</span></p><p style="margin:0in; padding-top:0px; padding-bottom:0px; font-size:10.5pt"><span style="margin:0px; padding:0px; font-family:Calibri"> </span><span style="margin:0px; padding:0px; font-family:宋体">恢复状态,其实玩过单机剧情类游戏的人都会马上想到“存档”这个功能。“存档”功能在某种意义上就是备忘录的一种应用。这里即以我最喜欢的游戏</span><span style="margin:0px; padding:0px; font-family:Calibri">Warcraft</span><span style="margin:0px; padding:0px; font-family:Calibri"> </span><span style="margin:0px; padding:0px; font-family:Calibri">III</span><span style="margin:0px; padding:0px; font-family:宋体">为示例。</span></p><p style="margin:0in; padding-top:0px; padding-bottom:0px; font-family:宋体; font-size:10.5pt"><span style="margin:0px; padding:0px; font-weight:bold">类图:</span></p><p style="margin:0in; padding-top:0px; padding-bottom:0px; font-family:宋体; font-size:10.5pt"><span style="margin:0px; padding:0px; font-weight:bold"><img src="image/29afc1b4d8442e42226d2d29ea16490f.jpg" alt="" style="border:none; max-width:100%"/></span></p><p style="margin:0in; padding-top:0px; padding-bottom:0px; font-size:10.5pt; line-height:22px; font-family:宋体"><span style="margin:0px; padding:0px; font-weight:bold">参与者:</span></p><ol type="1" style="margin:0in 0px 0in 0.375in; padding:0px; font-size:10.5pt; line-height:22px; direction:ltr; unicode-bidi:embed; font-family:宋体"><li value="1" style="margin:0px 0px 0px 40px; padding:0px; list-style:decimal; vertical-align:middle"><span style="margin:0px; padding:0px; font-family:Calibri; font-size:10.5pt">Warcraft</span><span style="margin:0px; padding:0px; font-size:10.5pt">,也即</span><span style="margin:0px; padding:0px; font-family:Calibri; font-size:10.5pt">Originator</span><span style="margin:0px; padding:0px; font-size:10.5pt">,它的状态需要被记录以及恢复。</span></li></ol><ol type="1" style="margin:0in 0px 0in 0.375in; padding:0px; font-size:10.5pt; line-height:22px; direction:ltr; unicode-bidi:embed; font-family:宋体"><li value="2" style="margin:0px 0px 0px 40px; padding:0px; list-style:decimal; vertical-align:middle"><span style="margin:0px; padding:0px; font-family:Calibri; font-size:10.5pt">Memento</span><span style="margin:0px; padding:0px; font-size:10.5pt">,抽象出</span><span style="margin:0px; padding:0px; font-family:Calibri; font-size:10.5pt">Warcraft</span><span style="margin:0px; padding:0px; font-size:10.5pt">的内部状态,并提供操作方法。</span></li></ol><ol type="1" style="margin:0in 0px 0in 0.375in; padding:0px; font-size:10.5pt; line-height:22px; direction:ltr; unicode-bidi:embed; font-family:宋体"><li value="3" style="margin:0px 0px 0px 40px; padding:0px; list-style:decimal; vertical-align:middle"><span style="margin:0px; padding:0px; font-family:Calibri; font-size:10.5pt">Caretaker</span><span style="margin:0px; padding:0px; font-size:10.5pt">,管理</span><span style="margin:0px; padding:0px; font-family:Calibri; font-size:10.5pt">Memento</span><span style="margin:0px; padding:0px; font-size:10.5pt">,并向外提供记录及恢复状态的方法,但是不了解具体的执行过程。</span></li></ol><p style="margin:0in; padding-top:0px; padding-bottom:0px; font-size:10.5pt; line-height:22px; font-family:宋体"><span style="margin:0px; padding:0px; font-weight:bold">示例代码:</span></p><p style="margin:0in; padding-top:0px; padding-bottom:0px; font-size:10.5pt; line-height:22px; font-family:宋体"><span style="margin:0px; padding:0px; font-weight:bold"/></p><pre code_snippet_id="224992" snippet_file_name="blog_20140308_1_6174052" name="code" class="csharp">using System;
using System.Collections.Generic;
using System.Text;
namespace Pattern19
{
class Warcrift
{
private string role;
public string Role
{
get { return role; }
set { role = value; }
}
public Memento CreateMemento()
{
return (new Memento(role));
}
public void SetMemento(Memento memento)
{
role = memento.Role;
}
public void Start()
{
Console.WriteLine("There is a " + role);
}
}
class Memento
{
private string role;
public Memento(string _role)
{
this.role = _role;
}
public string Role
{
get { return role; }
}
}
class Caretaker
{
private Memento memento;
public Memento Memento
{
get { return memento; }
set { memento = value; }
}
}
class Program
{
static void Main(string[] args)
{
// 初始角色是英雄
Warcrift war3 = new Warcrift();
war3.Role = "Hero";
war3.Start();
Caretaker caretaker = new Caretaker();
caretaker.Memento = war3.CreateMemento();
// 更换角色为小兵
war3.Role = "Soldier";
war3.Start();
// 退回到初始状态
war3.SetMemento(caretaker.Memento);
war3.Start();
}
}
}</pre><div style="font-size:14px; margin:0px; padding:0px; color:rgb(84,84,84); font-family:Tahoma,'Microsoft Yahei'; line-height:22px"><span style="margin:0px; padding:0px; font-family:宋体; font-size:10.5pt"><strong>适用性:</strong></span></div><ol type="1" style="font-size:10.5pt; margin:0in 0px 0in 0.375in; padding:0px; color:rgb(84,84,84); line-height:22px; direction:ltr; unicode-bidi:embed; font-family:宋体"><li value="1" style="margin:0px 0px 0px 40px; padding:0px; list-style:decimal; vertical-align:middle"><span style="margin:0px; padding:0px; font-size:10.5pt">必须保存一个对象在某一个时刻</span><span style="margin:0px; padding:0px; font-family:Calibri; font-size:10.5pt">(</span><span style="margin:0px; padding:0px; font-size:10.5pt">部分</span><span style="margin:0px; padding:0px; font-family:Calibri; font-size:10.5pt">)</span><span style="margin:0px; padding:0px; font-size:10.5pt">的</span><span style="margin:0px; padding:0px; font-size:10.5pt">状态</span><span style="margin:0px; padding:0px; font-family:Calibri; font-size:10.5pt">, </span><span style="margin:0px; padding:0px; font-size:10.5pt">这样以后需要它时才能恢复到先前的状</span><span style="margin:0px; padding:0px; font-family:Calibri; font-size:10.5pt">态。</span></li></ol><ol type="1" style="font-size:10.5pt; margin:0in 0px 0in 0.375in; padding:0px; color:rgb(84,84,84); line-height:22px; direction:ltr; unicode-bidi:embed; font-family:宋体"><li value="2" style="margin:0px 0px 0px 40px; padding:0px; list-style:decimal; vertical-align:middle"><span style="margin:0px; padding:0px; font-size:10.5pt">如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象</span><span style="margin:0px; padding:0px; font-family:Calibri; font-size:10.5pt">的封装性。</span></li></ol><p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px"/><p style="font-size:10.5pt; margin:0in; padding-top:0px; padding-bottom:0px; color:rgb(84,84,84); line-height:22px; font-family:宋体"><span style="margin:0px; padding:0px; font-weight:bold">优缺点:</span></p><ol type="1" style="font-size:10.5pt; margin:0in 0px 0in 0.375in; padding:0px; color:rgb(84,84,84); line-height:22px; direction:ltr; unicode-bidi:embed; font-family:宋体"><li value="1" style="margin:0px 0px 0px 40px; padding:0px; list-style:decimal; vertical-align:middle"><span style="margin:0px; padding:0px; font-size:10.5pt">优点,降低对象之间的耦合度,还降低管理对象的复杂度。</span></li></ol><ol type="1" style="font-size:10.5pt; margin:0in 0px 0in 0.375in; padding:0px; color:rgb(84,84,84); line-height:22px; direction:ltr; unicode-bidi:embed; font-family:宋体"><li value="2" style="margin:0px 0px 0px 40px; padding:0px; list-style:decimal; vertical-align:middle"><span style="margin:0px; padding:0px; font-size:10.5pt">缺点,如果需要存储的信息非常多,将会赞成非常大的开销。</span></li></ol><p style="font-size:10.5pt; margin:0in; padding-top:0px; padding-bottom:0px; color:rgb(84,84,84); line-height:22px; font-family:宋体"><span style="margin:0px; padding:0px; font-weight:bold">参考资料:</span></p><ol type="1" style="font-size:10.5pt; margin:0in 0px 0in 0.375in; padding:0px; color:rgb(84,84,84); line-height:22px; direction:ltr; unicode-bidi:embed; font-family:宋体"><li value="1" style="margin:0px 0px 0px 40px; padding:0px; list-style:decimal; vertical-align:middle"><span style="margin:0px; padding:0px; font-size:10.5pt">《设计模式——可复用面向对象软件基础》</span></li></ol><ol type="1" style="font-size:10.5pt; margin:0in 0px 0in 0.375in; padding:0px; color:rgb(84,84,84); line-height:22px; direction:ltr; unicode-bidi:embed; font-family:宋体"><li value="2" style="margin:0px 0px 0px 40px; padding:0px; list-style:decimal; vertical-align:middle"><span style="margin:0px; padding:0px; font-size:10.5pt">《大话设计模式》</span></li></ol><br/><br/><p/></div></div></div></td></tr></tbody></table>
- 前言
- 设计模式六大原则
- 1——创建型模式之简单工厂模式
- 2——创建型模式之工厂方法模式
- 3——创建型模式之抽象工厂模式
- 4——创建型模式之单例模式
- 5——创建型模式之建造者模式
- 6——创建型模式之原型模式
- 7——结构型模式之适配器模式
- 8——结构型模式之桥接模式
- 9——结构型模式之组合模式
- 10——结构型模式之装饰者模式
- 11——结构型模式之外观模式
- 12——结构型模式之享元模式
- 13——结构型模式之代理模式
- 14——行为型模式之职责链模式
- 15——行为型模式之命令模式
- 16——行为型模式之解释器模式
- 17——行为型模式之迭代器模式
- 18——行为型模式之中介者模式
- 19——行为型模式之备忘录模式
- 20——行为型模式之观察者模式
- 21——行为型模式之状态模式
- 22——行为型模式之策略模式
- 23——行为型模式之模板方法模型
- 24——行为型模式之访问者模式
- 设计模式总结