Wednesday, August 17, 2011

Memento Design Pattern

Memento design pattern is the one of the behavioral design patterns. It's used to keep internal state information of an object without violating encapsulation in order to restore the object into initial state when needed.

For instance, user changed some information of a product. But user realized that there is some mistake and it's needed to rollback. Previous state of product object should be holded. So that, user can easily restore prior product information.

In memento design pattern there are 3 elements which are Originator, Memento and Caretaker class. Originator class is the actual class containing some properties; Memento is used to keep values of Originator object; and Caretaker includes Memento class and take care to keep internal state of Originator objects' values.



Here I took an example to show how you can implement memento design pattern into your system. We have Configuration class which represents Originator, ConfigurationMemory class plays Caretaker role and finally ConfigurationMemento class has properties to hold values of Originator class.

   1:  public interface IConfiguration
   2:  {
   3:      string IP { get; set; }
   4:      string ServerName { get; set; }
   5:      int PoolSize { get; set; }
   6:  }
   7:   
   8:  // Originator 
   9:  public class Configuration : IConfiguration
  10:  { 
  11:      public string IP { get; set; }
  12:      public string ServerName { get; set; }
  13:      public int PoolSize { get; set; }
  14:   
  15:      public ConfigurationMemento SaveState() 
  16:      {
  17:          return new ConfigurationMemento(this.IP, this.ServerName, this.PoolSize);
  18:      }
  19:   
  20:      public void RestoreState(ConfigurationMemento memento) 
  21:      {
  22:          this.IP = memento.IP;
  23:          this.ServerName = memento.ServerName;
  24:          this.PoolSize = memento.PoolSize;
  25:      }
  26:  }
  27:   
  28:  // Caretaker
  29:  public class ConfigurationMemory
  30:  {
  31:      private ConfigurationMemento memento;
  32:   
  33:      public ConfigurationMemento Get()
  34:      {
  35:          return memento;
  36:      }
  37:   
  38:      public void Set(ConfigurationMemento memento)
  39:      {
  40:         this.memento = memento;
  41:      }
  42:  }
  43:   
  44:  // Memento
  45:  public class ConfigurationMemento : IConfiguration
  46:  {
  47:      public string IP { get; set; }
  48:      public string ServerName { get; set; }
  49:      public int PoolSize { get; set; }
  50:   
  51:      public ConfigurationMemento(string ip, string serverName, int poolSize)
  52:      {
  53:          this.IP = ip;
  54:          this.ServerName = serverName;
  55:          this.PoolSize = poolSize;
  56:      }
  57:  }

Implementation Memento Design Pattern :

   1:  static void Main(string[] args)
   2:  {
   3:      Configuration config = new Configuration();
   4:      config.IP = "10.10.10.11";
   5:      config.ServerName = "WebServer01";
   6:      config.PoolSize = 15;
   7:   
   8:      Display(config);
   9:   
  10:      ConfigurationMemory memory = new ConfigurationMemory();
  11:      memory.Set(config.SaveState());
  12:   
  13:      config.IP = "10.0.10.12";
  14:      config.ServerName = "WebServer02";
  15:      config.PoolSize = 25;
  16:      Display(config);
  17:   
  18:      config.RestoreState(memory.Get());
  19:      Display(config);
  20:  }
  21:  static void Display(IConfiguration config)
  22:  {
  23:      Console.WriteLine(config.IP);
  24:      Console.WriteLine(config.ServerName);
  25:      Console.WriteLine(config.PoolSize);
  26:      Console.WriteLine();
  27:  }

As you see client never access Memento object (ConfigurationMemento). Client can only interact with Memento object through the Caretaker class (ConfigurationMemory)

At line 11 : SaveState() method is invoked and the return value is used as a parameter passed to Set() method of ConfigurationMemory object to hold current state of Configuration object.

At line 13-15 : Values of Configuration object are changed.

At line 18 : RestoreState() method is called and former state value of Configuration object is passed to the method in order to set old values to Configuration object.

Output should be :
10.10.10.11
WebServer01
15

10.0.10.12
WebServer02
25

10.10.10.11
WebServer01
15

0 comments: