设计模式23:Memento Pattern (备忘录模式)
英文原文:http://www.dofactory.com/Patterns/PatternMemento.aspx
一、Memento Pattern (备忘录模式)
Define:Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later.
定义:在不违反封装性,捕获和使得一个对象的内状态具体化,以至于这个对象可以被存储于这个状态之后。
二、UML类图
- Memento (Memento)
- stores internal state of the Originator object. The memento may store as much or as little of the originator's internal state as necessary at its originator's discretion.
- protect against access by objects of other than the originator. Mementos have effectively two interfaces. Caretaker sees a narrow interface to the Memento -- it can only pass the memento to the other objects. Originator, in contrast, sees a wide interface, one that lets it access all the data necessary to restore itself to its previous state. Ideally, only the originator that produces the memento would be permitted to access the memento's internal state.
- Originator (SalesProspect)
- creates a memento containing a snapshot of its current internal state.
- uses the memento to restore its internal state
- Caretaker (Caretaker)
- is responsible for the memento's safekeeping
-
never operates on or examines the contents of a memento.
三、Memento Pattern (备忘录模式)实例代码
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace Memento_Pattern
- {
- /// <summary>
- /// MainApp startup class for Structural
- /// Memento Design Pattern.
- /// </summary>
- class MainApp
- {
- /// <summary>
- /// Entry point into console application.
- /// </summary>
- static void Main()
- {
- Originator o = new Originator();
- o.State = "On";
- // Store internal state
- Caretaker c = new Caretaker();
- c.Memento = o.CreateMemento();
- // Continue changing originator
- o.State = "Off";
- // Restore saved state
- o.SetMemento(c.Memento);
- // Wait for user
- Console.ReadKey();
- }
- }
- /// <summary>
- /// The 'Originator' class
- /// </summary>
- class Originator
- {
- private string _state;
- // Property
- public string State
- {
- get { return _state; }
- set
- {
- _state = value;
- Console.WriteLine("State = " + _state);
- }
- }
- // Creates memento
- public Memento CreateMemento()
- {
- return (new Memento(_state));
- }
- // Restores original state
- public void SetMemento(Memento memento)
- {
- Console.WriteLine("Restoring state...");
- State = memento.State;
- }
- }
- /// <summary>
- /// The 'Memento' class
- /// </summary>
- class Memento
- {
- private string _state;
- // Constructor
- public Memento(string state)
- {
- this._state = state;
- }
- // Gets or sets state
- public string State
- {
- get { return _state; }
- }
- }
- /// <summary>
- /// The 'Caretaker' class
- /// </summary>
- class Caretaker
- {
- private Memento _memento;
- // Gets or sets memento
- public Memento Memento
- {
- set { _memento = value; }
- get { return _memento; }
- }
- }
- }
四、使用备忘录模式的实例代码
This real-world code demonstrates the Memento pattern which temporarily saves and then restores the SalesProspect's internal state.
临时保存和恢复SalesProspect的内部状态
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace Memento_Pattern
- {
- /// <summary>
- /// MainApp startup class for Real-World
- /// Memento Design Pattern.
- /// </summary>
- class MainApp
- {
- /// <summary>
- /// Entry point into console application.
- /// </summary>
- static void Main()
- {
- SalesProspect s = new SalesProspect();
- s.Name = "Noel van Halen";
- s.Phone = "(412) 256-0990";
- s.Budget = 25000.0;
- // Store internal state
- ProspectMemory m = new ProspectMemory();
- m.Memento = s.SaveMemento();
- // Continue changing originator
- s.Name = "Leo Welch";
- s.Phone = "(310) 209-7111";
- s.Budget = 1000000.0;
- // Restore saved state
- s.RestoreMemento(m.Memento);
- // Wait for user
- Console.ReadKey();
- }
- }
- /// <summary>
- /// The 'Originator' class
- /// </summary>
- class SalesProspect
- {
- private string _name;
- private string _phone;
- private double _budget;
- // Gets or sets name
- public string Name
- {
- get { return _name; }
- set
- {
- _name = value;
- Console.WriteLine("Name: " + _name);
- }
- }
- // Gets or sets phone
- public string Phone
- {
- get { return _phone; }
- set
- {
- _phone = value;
- Console.WriteLine("Phone: " + _phone);
- }
- }
- // Gets or sets budget
- public double Budget
- {
- get { return _budget; }
- set
- {
- _budget = value;
- Console.WriteLine("Budget: " + _budget);
- }
- }
- // Stores memento
- public Memento SaveMemento()
- {
- Console.WriteLine("/nSaving state --/n");
- return new Memento(_name, _phone, _budget);
- }
- // Restores memento
- public void RestoreMemento(Memento memento)
- {
- Console.WriteLine("/nRestoring state --/n");
- this.Name = memento.Name;
- this.Phone = memento.Phone;
- this.Budget = memento.Budget;
- }
- }
- /// <summary>
- /// The 'Memento' class
- /// </summary>
- class Memento
- {
- private string _name;
- private string _phone;
- private double _budget;
- // Constructor
- public Memento(string name, string phone, double budget)
- {
- this._name = name;
- this._phone = phone;
- this._budget = budget;
- }
- // Gets or sets name
- public string Name
- {
- get { return _name; }
- set { _name = value; }
- }
- // Gets or set phone
- public string Phone
- {
- get { return _phone; }
- set { _phone = value; }
- }
- // Gets or sets budget
- public double Budget
- {
- get { return _budget; }
- set { _budget = value; }
- }
- }
- /// <summary>
- /// The 'Caretaker' class
- /// </summary>
- class ProspectMemory
- {
- private Memento _memento;
- // Property
- public Memento Memento
- {
- set { _memento = value; }
- get { return _memento; }
- }
- }
- }
乐在其中设计模式(C#) - 备忘录模式(Memento Pattern)
乐在其中设计模式(C#) - 备忘录模式(Memento Pattern)
作者:webabcd
介绍
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。
示例
有一个Message实体类,某个对象对它的操作有Insert()方法,只有在插入时间符合要求的情况下才能插入成功,因此要求可以保存和恢复Message对象的状态,插入失败后则恢复Message对象的状态,然后只更新时间,再次插入。
MessageModel
using System;
using System.Collections.Generic;
using System.Text;
namespace Pattern.Memento
{
/// <summary>
/// Message实体类(Memento)
/// </summary>
public class MessageModel
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="msg">Message内容</param>
/// <param name="pt">Message发布时间</param>
public MessageModel(string msg, DateTime pt)
{
this._message = msg;
this._publishTime = pt;
}
private string _message;
/// <summary>
/// Message内容
/// </summary>
public string Message
{
get { return _message; }
set { _message = value; }
}
private DateTime _publishTime;
/// <summary>
/// Message发布时间
/// </summary>
public DateTime PublishTime
{
get { return _publishTime; }
set { _publishTime = value; }
}
}
}
MessageModelCaretaker
using System;
using System.Collections.Generic;
using System.Text;
namespace Pattern.Memento
{
/// <summary>
/// Memento管理者(Caretaker)
/// </summary>
public class MessageModelCaretaker
{
private MessageModel _messageModel;
/// <summary>
/// Message实体对象(Memento)
/// </summary>
public MessageModel MessageModel
{
get { return _messageModel; }
set { _messageModel = value; }
}
}
}
SqlMessage
using System;
using System.Collections.Generic;
using System.Text;
namespace Pattern.Memento
{
/// <summary>
/// Sql方式操作Message(Originator)
/// </summary>
public class SqlMessage
{
private string _message;
/// <summary>
/// Message内容
/// </summary>
public string Message
{
get { return _message; }
set { _message = value; }
}
private DateTime _publishTime;
/// <summary>
/// Message发布时间
/// </summary>
public DateTime PublishTime
{
get { return _publishTime; }
set { _publishTime = value; }
}
/// <summary>
/// 插入Message
/// </summary>
/// <param name="mm">Message实体对象</param>
/// <returns></returns>
public bool Insert(MessageModel mm)
{
// 秒数可以被5整除时,则执行插入操作
if (mm.PublishTime.Second % 5 == 0)
{
// 代码略
return true;
}
else
{
return false;
}
}
/// <summary>
/// 保存Memento
/// </summary>
/// <returns></returns>
public MessageModel SaveMemento()
{
return new MessageModel(_message, _publishTime);
}
/// <summary>
/// 恢复Memento
/// </summary>
/// <param name="mm"></param>
public void RestoreMemento(MessageModel mm)
{
this._message = mm.Message;
this._publishTime = mm.PublishTime;
}
}
}
Test
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Pattern.Memento;
public partial class Memento : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
SqlMessage m = new SqlMessage();
m.Message = "Message内容";
m.PublishTime = DateTime.Now;
MessageModelCaretaker mmc = new MessageModelCaretaker();
mmc.MessageModel = m.SaveMemento();
bool bln = false;
while (!bln)
{
bln = m.Insert(new MessageModel(m.Message, m.PublishTime));
Response.Write(m.Message + " " + m.PublishTime.ToString() + " " + bln.ToString());
Response.Write("<br />");
if (!bln)
{
System.Threading.Thread.Sleep(1000);
m.RestoreMemento(mmc.MessageModel);
m.PublishTime = DateTime.Now;
}
}
}
}
运行结果
Message内容 2007-5-23 21:32:13 False
Message内容 2007-5-23 21:32:14 False
Message内容 2007-5-23 21:32:15 True
参考
http://www.dofactory.com/Patterns/PatternMemento.aspx
OK
[源码下载]