备忘录模式:备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捉住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。
名称 Memento
结构  
意图 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
适用性
  • 必须保存一个对象在某一个时刻的(部分)状态, 这样以后需要时它才能恢复到先前的状态。
  • 如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。
Code Example  
  1// Memento
  2
  3// Intent: "Without violating encapsulation, capture and externalize an 
  4// object's internal state so that an object can be restored to this 
  5// state later." 
  6
  7// For further information, read "Design Patterns", p283, Gamma et al.,
  8// Addison-Wesley, ISBN:0-201-63361-2
  9
 10/* Notes:
 11 * We often have client code that wishes to record the current state of an 
 12 * object, without being interested in the actual data values (this is 
 13 * needed for undo and checkpointing). To support this behavior, we can have
 14 * the object record its internal data in a helper class called a memento, and
 15 * the client code can treat this as an opaque store of the object's state. 
 16 * At some later point, the client can pass the memento back into the object, 
 17 * to restore it to the previous state. 
 18 */

 19 
 20namespace Memento_DesignPattern
 21{
 22    using System;
 23
 24    class Originator 
 25    {
 26        private double manufacturer=0;
 27        private double distributor = 0;
 28        private double retailer = 0;
 29
 30        public void MakeSale(double purchasePrice)
 31        {
 32            // We assume sales are divided equally amount the three
 33            manufacturer += purchasePrice * .40;
 34            distributor += purchasePrice *.3;
 35            retailer += purchasePrice *.3;
 36            // Note: to avoid rounding errors for real money handling 
 37            // apps, we should be using decimal integers
 38            // (but hey, this is just a demo!)
 39        }

 40
 41        public Memento CreateMemento()
 42        {
 43            return (new Memento(manufacturer, distributor, retailer));            
 44        }

 45        
 46        public void SetMemento(Memento m)
 47        {
 48            manufacturer = m.A;
 49            distributor = m.B;
 50            retailer = m.C;
 51        }
        
 52    }

 53
 54    class Memento 
 55    {
 56        private double iA;
 57        private double iB;
 58        private double iC;
 59
 60        public Memento(double a, double b, double c)
 61        {
 62            iA = a;
 63            iB = b;
 64            iC = c;
 65        }

 66
 67        public double A 
 68        {
 69            get 
 70            {
 71                return iA;
 72            }

 73        }

 74
 75        public double B 
 76        {
 77            get 
 78            {
 79                return iB;
 80            }

 81        }

 82
 83        public double C 
 84        {
 85            get 
 86            {
 87                return iC;
 88            }

 89        }

 90    }

 91
 92    class caretaker 
 93    {
 94        
 95    }

 96
 97        /// <summary>
 98    ///    Summary description for Client.
 99    /// </summary>

100    public class Client
101    {
102        public static int Main(string[] args)
103        {              
104            Originator o = new Originator();
105            
106            // Assume that during the course of running an application 
107            // we we set various data in the originator
108            o.MakeSale(45.0);
109            o.MakeSale(60.0);
110
111            // Now we wish to record the state of the object
112            Memento m = o.CreateMemento();
113
114            // We make further changes to the object
115            o.MakeSale(60.0);
116            o.MakeSale(10.0);
117            o.MakeSale(320.0);
118
119            // Then we decide ot change our minds, and revert to the saved state (and lose the changes since then)
120            o.SetMemento(m);
121
122            return 0;
123        }

124    }

125}

126
127