Поведенческие паттерны: Хранитель (Memento) C#
 
                        
                    Назначение:
Паттерн Хранитель (Memento) — позволяет выносить внутреннее состояние объекта за его пределы для последующего возможного восстановления объекта без нарушения принципа инкапсуляции.
- Не нарушая инкапсуляции, паттерн Memento получает и сохраняет за пределами объекта его внутреннее состояние так, чтобы позже можно было восстановить объект в таком же состоянии.
- Является средством для инкапсуляции "контрольных точек" программы.
- Паттерн Memento придает операциям "Отмена" (undo) или "Откат" (rollback) статус "полноценного объекта".
Когда использовать Memento?
- 
	Когда нужно сохранить состояние объекта для возможного последующего восстановления; 
- 
	Когда сохранение состояния должно проходить без нарушения принципа инкапсуляции; 
UML схема паттерна Хранитель:
 
Участники
- 
	Memento: хранитель, который сохраняет состояние объекта Originator и предоставляет полный доступ только этому объекту Originator 
- 
	Originator: создает объект хранителя для сохранения своего состояния 
- 
	Caretaker: выполняет только функцию хранения объекта Memento, в то же время у него нет полного доступа к хранителю и никаких других операций над хранителем, кроме собственно сохранения, он не производит 
Схема использования паттерна memento из реальной жизни:

Реализация Поведенческого шаблона "Memento" на C#
  class MainApp
  {
    
    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; }
    }
} 
Output
State = On
State = Off
Restoring state:
State = On
Преимущества и недостатки хранителя
Преимущества Memento:
- Не нарушает инкапсуляции исходного объекта.
- Упрощает структуру исходного объекта. Ему не нужно хранить историю версий своего состояния.
Недостатки Memento:
- Требует много памяти, если клиенты слишком часто создают снимки.
- Может повлечь дополнительные издержки памяти, если объекты, хранящие историю, не освобождают ресурсы, занятые устаревшими снимками.
- В некоторых языках программирования (таких как PHP, Python, JavaScript и др) сложно гарантировать, чтобы только исходный объект имел доступ к состоянию снимка.
 
                    