<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——行為型模式之訪問者模式
- 設計模式總結