备忘录模式(Memento Pattern)

对象状态的回溯:
    对象状态的变化无端,如何回溯/恢复对象在某个点的状态?
                        备忘录模式(Memento Pattern)
动机:
    在软件构建过程中,某些对象的状态在转换过程中,可能由于某种需要,要求程序能够回溯到对象之前处于某个点时的状态。如果使用一些公有接口来让其他对象得到对象的状态,便会暴露对象的细节实现。
    如何实现对象状态的良好保存与恢复?但同时又不会因此而破坏对象本身的封装性。

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

          备忘录模式(Memento Pattern)
适用性:
    1.必须保存一个对象某一个时刻的(部分)状态,这样以后需要时它才能恢复到先前的状态。
    2.如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。


代码实现:
 1       class  Memento
 2      {
 3           private   string  name;
 4           private   string  phone;
 5           private   double  budget;
 6 
 7           // Constructor
 8           public  Memento( string  name,  string  phone,  double  budget)
 9          {
10               this .name  =  name;
11               this .phone  =  phone;
12               this .budget  =  budget;
13          }
14           // Properties
15           public   string  Name
16          {
17               get  {  return  name; }
18               set  { name  =  value; }
19          }
20           public   string  Phone
21          {
22               get  {  return  phone; }
23               set  { phone  =  value; }
24          }
25           public   double  Budget
26          {
27               get  {  return  budget; }
28               set  { budget  =  value; }
29          }
30      }

 1       class  ProspectMemory
 2      {
 3           private  Memento memento;
 4 
 5           // Property
 6           public  Memento Memento
 7          {
 8               set  { memento  =  value; }
 9               get  {  return  memento; }
10          }
11      }

 1     // Originator
 2       class  SalesProspect
 3      {
 4           private   string  name;
 5           private   string  phone;
 6           private   double  budget;
 7 
 8           // Properties
 9           public   string  Name
10          {
11               get  {  return  name; }
12               set  { name  =  value; Console.WriteLine( " Name: "   +  name); }
13          }
14           public   string  Phone
15          {
16               get  {  return  phone; }
17               set  { phone  =  value; Console.WriteLine( " Phone: "   +  phone); }
18          }
19           public   double  Budget
20          {
21               get  {  return  Budget; }
22               set  { budget  =  value; Console.WriteLine( " Budget: "   +  budget); }
23          }
24           public  Memento SaveMemento()
25          {
26              Console.WriteLine( " \nSaving state --\n " );
27               return   new  Memento(name, phone, budget);
28          }
29           public   void  RestoreMemento(Memento memento)
30          {
31              Console.WriteLine( " \nRestoring state --\n " );
32               this .Name  =  memento.Name;
33               this .Phone  =  memento.Phone;
34               this .Budget  =  memento.Budget;
35          }
36      }

 1      class  Program
 2      {
 3           static   void  Main( string [] args)
 4          {
 5              SalesProspect s  =   new  SalesProspect();
 6              s.Name  =   " xiaoming " ;
 7              s.Phone  =   " (010)65236523 " ;
 8              s.Budget  =   28000.0 ;
 9 
10               // Store internal state
11              ProspectMemory m  =   new  ProspectMemory();
12              m.Memento  =  s.SaveMemento();
13 
14               // Continue changing originator
15              s.Name  =   " deke " ;
16              s.Phone  =   " (029)85423657 " ;
17              s.Budget  =   80000.0 ;
18 
19               // Restore saved state 
20              s.RestoreMemento(m.Memento);
21 
22               // Wait for user 
23              Console.Read();
24          }
25      }

Memento需要注意的几个要点:
    1.备忘录(Memento)存储原发器(Originator)对象的内部状态,在需要时恢复原发器状态。Memento模式适用于“由原发器管理,却又必须存储在原发器之外的信息”。
    2.在实现Memento模式中,要防止原发器以外的对象访问备忘录对象。备忘录对象有两个接口,一个为原发器的宽接口;一个为其他对象使用的窄接口。
    3.在实现Memento模式时,要考虑拷贝对象状态的效率问题,如果对象开销比较大,可以采用某种增量式改变来改进Memento模式。


你可能感兴趣的:(Pattern)