备忘录模式(Memento Pattern)

设计模式 - 吕震宇

.NET设计模式系列文章

薛敬明的专栏

乐在其中设计模式(C#)

设计模式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 (备忘录模式)实例代码

    [c-sharp] view plain copy
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5.   
    6. namespace Memento_Pattern  
    7. {  
    8.     /// <summary>  
    9.   
    10.     /// MainApp startup class for Structural   
    11.   
    12.     /// Memento Design Pattern.  
    13.   
    14.     /// </summary>  
    15.   
    16.     class MainApp  
    17.     {  
    18.   
    19.         /// <summary>  
    20.   
    21.         /// Entry point into console application.  
    22.   
    23.         /// </summary>  
    24.   
    25.         static void Main()  
    26.         {  
    27.   
    28.             Originator o = new Originator();  
    29.   
    30.             o.State = "On";  
    31.   
    32.   
    33.   
    34.             // Store internal state  
    35.   
    36.             Caretaker c = new Caretaker();  
    37.   
    38.             c.Memento = o.CreateMemento();  
    39.   
    40.   
    41.   
    42.             // Continue changing originator  
    43.   
    44.             o.State = "Off";  
    45.   
    46.   
    47.   
    48.             // Restore saved state  
    49.   
    50.             o.SetMemento(c.Memento);  
    51.   
    52.   
    53.   
    54.             // Wait for user  
    55.   
    56.             Console.ReadKey();  
    57.   
    58.         }  
    59.   
    60.     }  
    61.   
    62.   
    63.   
    64.     /// <summary>  
    65.   
    66.     /// The 'Originator' class  
    67.   
    68.     /// </summary>  
    69.   
    70.     class Originator  
    71.     {  
    72.   
    73.         private string _state;  
    74.   
    75.   
    76.   
    77.         // Property  
    78.   
    79.         public string State  
    80.         {  
    81.   
    82.             get { return _state; }  
    83.   
    84.             set  
    85.             {  
    86.   
    87.                 _state = value;  
    88.   
    89.                 Console.WriteLine("State = " + _state);  
    90.   
    91.             }  
    92.   
    93.         }  
    94.   
    95.   
    96.   
    97.         // Creates memento   
    98.   
    99.         public Memento CreateMemento()  
    100.         {  
    101.   
    102.             return (new Memento(_state));  
    103.   
    104.         }  
    105.   
    106.   
    107.   
    108.         // Restores original state  
    109.   
    110.         public void SetMemento(Memento memento)  
    111.         {  
    112.   
    113.             Console.WriteLine("Restoring state...");  
    114.   
    115.             State = memento.State;  
    116.   
    117.         }  
    118.   
    119.     }  
    120.   
    121.   
    122.   
    123.     /// <summary>  
    124.   
    125.     /// The 'Memento' class  
    126.   
    127.     /// </summary>  
    128.   
    129.     class Memento  
    130.     {  
    131.   
    132.         private string _state;  
    133.   
    134.   
    135.   
    136.         // Constructor  
    137.   
    138.         public Memento(string state)  
    139.         {  
    140.   
    141.             this._state = state;  
    142.   
    143.         }  
    144.   
    145.   
    146.   
    147.         // Gets or sets state  
    148.   
    149.         public string State  
    150.         {  
    151.   
    152.             get { return _state; }  
    153.   
    154.         }  
    155.   
    156.     }  
    157.   
    158.   
    159.   
    160.     /// <summary>  
    161.   
    162.     /// The 'Caretaker' class  
    163.   
    164.     /// </summary>  
    165.   
    166.     class Caretaker  
    167.     {  
    168.   
    169.         private Memento _memento;  
    170.   
    171.   
    172.   
    173.         // Gets or sets memento  
    174.   
    175.         public Memento Memento  
    176.         {  
    177.   
    178.             set { _memento = value; }  
    179.   
    180.             get { return _memento; }  
    181.   
    182.         }  
    183.   
    184.     }  
    185. }  

    四、使用备忘录模式的实例代码

    This real-world code demonstrates the Memento pattern which temporarily saves and then restores the SalesProspect's internal state.

    临时保存和恢复SalesProspect的内部状态

    [c-sharp] view plain copy
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5.   
    6. namespace Memento_Pattern  
    7. {  
    8.     /// <summary>  
    9.   
    10.     /// MainApp startup class for Real-World   
    11.   
    12.     /// Memento Design Pattern.  
    13.   
    14.     /// </summary>  
    15.   
    16.     class MainApp  
    17.     {  
    18.   
    19.         /// <summary>  
    20.   
    21.         /// Entry point into console application.  
    22.   
    23.         /// </summary>  
    24.   
    25.         static void Main()  
    26.         {  
    27.   
    28.             SalesProspect s = new SalesProspect();  
    29.   
    30.             s.Name = "Noel van Halen";  
    31.   
    32.             s.Phone = "(412) 256-0990";  
    33.   
    34.             s.Budget = 25000.0;  
    35.   
    36.   
    37.   
    38.             // Store internal state  
    39.   
    40.             ProspectMemory m = new ProspectMemory();  
    41.   
    42.             m.Memento = s.SaveMemento();  
    43.   
    44.   
    45.   
    46.             // Continue changing originator  
    47.   
    48.             s.Name = "Leo Welch";  
    49.   
    50.             s.Phone = "(310) 209-7111";  
    51.   
    52.             s.Budget = 1000000.0;  
    53.   
    54.   
    55.   
    56.             // Restore saved state  
    57.   
    58.             s.RestoreMemento(m.Memento);  
    59.   
    60.   
    61.   
    62.             // Wait for user  
    63.   
    64.             Console.ReadKey();  
    65.   
    66.         }  
    67.   
    68.     }  
    69.   
    70.   
    71.   
    72.     /// <summary>  
    73.   
    74.     /// The 'Originator' class  
    75.   
    76.     /// </summary>  
    77.   
    78.     class SalesProspect  
    79.     {  
    80.   
    81.         private string _name;  
    82.   
    83.         private string _phone;  
    84.   
    85.         private double _budget;  
    86.   
    87.   
    88.   
    89.         // Gets or sets name  
    90.   
    91.         public string Name  
    92.         {  
    93.   
    94.             get { return _name; }  
    95.   
    96.             set  
    97.             {  
    98.   
    99.                 _name = value;  
    100.   
    101.                 Console.WriteLine("Name:  " + _name);  
    102.   
    103.             }  
    104.   
    105.         }  
    106.   
    107.   
    108.   
    109.         // Gets or sets phone  
    110.   
    111.         public string Phone  
    112.         {  
    113.   
    114.             get { return _phone; }  
    115.   
    116.             set  
    117.             {  
    118.   
    119.                 _phone = value;  
    120.   
    121.                 Console.WriteLine("Phone: " + _phone);  
    122.   
    123.             }  
    124.   
    125.         }  
    126.   
    127.   
    128.   
    129.         // Gets or sets budget  
    130.   
    131.         public double Budget  
    132.         {  
    133.   
    134.             get { return _budget; }  
    135.   
    136.             set  
    137.             {  
    138.   
    139.                 _budget = value;  
    140.   
    141.                 Console.WriteLine("Budget: " + _budget);  
    142.   
    143.             }  
    144.   
    145.         }  
    146.   
    147.   
    148.   
    149.         // Stores memento  
    150.   
    151.         public Memento SaveMemento()  
    152.         {  
    153.   
    154.             Console.WriteLine("/nSaving state --/n");  
    155.   
    156.             return new Memento(_name, _phone, _budget);  
    157.   
    158.         }  
    159.   
    160.   
    161.   
    162.         // Restores memento  
    163.   
    164.         public void RestoreMemento(Memento memento)  
    165.         {  
    166.   
    167.             Console.WriteLine("/nRestoring state --/n");  
    168.   
    169.             this.Name = memento.Name;  
    170.   
    171.             this.Phone = memento.Phone;  
    172.   
    173.             this.Budget = memento.Budget;  
    174.   
    175.         }  
    176.   
    177.     }  
    178.   
    179.   
    180.   
    181.     /// <summary>  
    182.   
    183.     /// The 'Memento' class  
    184.   
    185.     /// </summary>  
    186.   
    187.     class Memento  
    188.     {  
    189.   
    190.         private string _name;  
    191.   
    192.         private string _phone;  
    193.   
    194.         private double _budget;  
    195.   
    196.   
    197.   
    198.         // Constructor  
    199.   
    200.         public Memento(string name, string phone, double budget)  
    201.         {  
    202.   
    203.             this._name = name;  
    204.   
    205.             this._phone = phone;  
    206.   
    207.             this._budget = budget;  
    208.   
    209.         }  
    210.   
    211.   
    212.   
    213.         // Gets or sets name  
    214.   
    215.         public string Name  
    216.         {  
    217.   
    218.             get { return _name; }  
    219.   
    220.             set { _name = value; }  
    221.   
    222.         }  
    223.   
    224.   
    225.   
    226.         // Gets or set phone  
    227.   
    228.         public string Phone  
    229.         {  
    230.   
    231.             get { return _phone; }  
    232.   
    233.             set { _phone = value; }  
    234.   
    235.         }  
    236.   
    237.   
    238.   
    239.         // Gets or sets budget  
    240.   
    241.         public double Budget  
    242.         {  
    243.   
    244.             get { return _budget; }  
    245.   
    246.             set { _budget = value; }  
    247.   
    248.         }  
    249.   
    250.     }  
    251.   
    252.   
    253.   
    254.     /// <summary>  
    255.   
    256.     /// The 'Caretaker' class  
    257.   
    258.     /// </summary>  
    259.   
    260.     class ProspectMemory  
    261.     {  
    262.   
    263.         private Memento _memento;  
    264.   
    265.   
    266.   
    267.         // Property  
    268.   
    269.         public Memento Memento  
    270.         {  
    271.   
    272.             set { _memento = value; }  
    273.   
    274.             get { return _memento; }  
    275.   
    276.         }  
    277.   
    278.     }  
    279. }  

    乐在其中设计模式(C#) - 备忘录模式(Memento Pattern)

    乐在其中设计模式(C#) - 备忘录模式(Memento Pattern)


    作者:webabcd


    介绍
    在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。


    示例
    有一个Message实体类,某个对象对它的操作有Insert()方法,只有在插入时间符合要求的情况下才能插入成功,因此要求可以保存和恢复Message对象的状态,插入失败后则恢复Message对象的状态,然后只更新时间,再次插入。
    备忘录模式(Memento Pattern)_第1张图片


    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
    [源码下载]



  • 你可能感兴趣的:(备忘录模式(Memento Pattern))