Friday, May 19, 2017

Memento design pattern

Problem statement :

•       Consider creating an gaming  application, which contains level 1 to 5.
•       The player will score different scores  and points at each level.
•       When the player reaches Level 1 the application will update the Score and Level (ex: Level =1 ; Score = 100 and other points).
•       When the player reaches Level 2 the application  will update the Score and Level (ex: Level =2 ; Score = 200 and other points).
•       When the player reaches Level 3 the application  will update the Score and Level (ex: Level =3 ; Score = 300 and other points).
•       When the player reaches Level 4  he scores 350 but he has lost a game life .
•       Now the application  should restrict moving  further level and should restore back to Level 3 with the Score = 300 and points, but it cannot as the application doesn't know the previous level  Score and points as they are already updated.
•       To overcome the above issue, we can use the Memento pattern.


What is Memento :


      •   Memento – Reminder, token, trophy. “Object to you keep to remember a person, place ,event”.
•       Memento pattern falls under behavioral pattern category. –    Behavioral design patterns are concerned with the interaction and  responsibility of objects.
•       The memento pattern is a software design  pattern that provides the ability to restore an object to its previous state (undo via rollback)
•       Memento means a reminder of past events . In Memento pattern, we do not create a copy of an object. We create Mementos that hold the state of an object and it might include full object or elements of an object that needs to be stored.
•       Memento protects encapsulation and avoids exposing originator's internal state and implementation.

Implementation : 

•       Originator : Class to hold the main data (level , score and points), i.e the data of the player
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 namespace MementoPattern  
 {  
   /// <summary>  
   /// Orignator class  
   /// </summary>  
   public class PlayerStatistics  
   {  
     public int LevelID { get; set; }  
     public int Score { get; set; }  
     public DateTime Time { get; set; }  
     public int Name { get; set; }  
     public int Points { get; set; }  
     public string GraphicType { get; set; }  
     /// <summary>  
     /// Save the player statics to a memento  
     /// </summary>  
     /// <param name="playerStatistics"></param>  
     /// <returns></returns>  
     public PlayerStatisticsMemento CreateMemento(PlayerStatistics playerStatistics)  
     {  
       return new PlayerStatisticsMemento(playerStatistics.LevelID, playerStatistics.Score, playerStatistics.Time, playerStatistics.Points);  
     }  
     /// <summary>  
     /// Restore the player statistics to a previous state held by memento  
     /// </summary>  
     /// <param name="checkPointMemento"></param>  
     public void SetMemento(PlayerStatisticsMemento checkPointMemento)  
     {  
       this.LevelID = checkPointMemento._LevelID;  
       this.Score = checkPointMemento._Score;  
       this.Time = checkPointMemento._Time;  
     }  
     public void PrintStatistics()  
     {  
       Console.WriteLine("CheckPoint Time:" + this.Time);  
       Console.WriteLine("Level is:" + this.LevelID);  
       Console.WriteLine("Score is:" + this.Score);  
     }  
   }  
 }  
•       Memento   : Class used to store  the snapshot of the origin data  (Originator class) only with the properties which are needed to be captured.
1:  using System;  
2:  using System.Collections.Generic;  
3:  using System.Linq;  
4:  using System.Text;  
5:  using System.Threading.Tasks;  
6:  namespace MementoPattern  
7:  {  
8:    /// <summary>  
9:    /// Memento  
10:    /// </summary>  
11:    public class PlayerStatisticsMemento  
12:    {  
13:      public int _LevelID { get; set; }  
14:      public int _Score { get; set; }  
15:      public DateTime _Time { get; set; }  
16:      public int _Points { get; set; }  
17:      public PlayerStatisticsMemento(int level, int score, DateTime time, int points)  
18:      {  
19:        this._LevelID = level;  
20:        this._Score = score;  
21:        this._Time = time;  
22:        this._Points = points;  
23:      }  
24:    }  
25:  }  

•      CareTaker : To hold  all the memento objects , i.e which holds the snapshot of the original data.
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 namespace MementoPattern  
 {  
   /// <summary>  
   /// Caretaker to hold the undo/redo.  
   /// </summary>  
   public class CareTaker  
   {  
     private static CareTaker _instance;  
     private PlayerStatisticsMemento _playerStaticsMemento;  
     private CareTaker()  
     {  
     }  
     public static CareTaker Instance  
     {  
       get  
       {  
         if (_instance == null)  
         {  
           _instance = new CareTaker();  
         }  
         return _instance;  
       }  
     }  
     public PlayerStatisticsMemento PlayerStaticsMemento  
     {  
       get  
       {  
         return _playerStaticsMemento;  
       }  
       set  
       {  
         _playerStaticsMemento = value;  
       }  
     }  
   }  
 }  

Main program:


1:  using System;  
2:  using System.Collections.Generic;  
3:  using System.Linq;  
4:  using System.Text;  
5:  using System.Threading.Tasks;  
6:  namespace MementoPattern  
7:  {  
8:    class Program  
9:    {  
10:      static void Main(string[] args)  
11:      {  
12:        PlayerStatistics _statistics = new PlayerStatistics();  
13:        _statistics.LevelID = 1;  
14:        _statistics.Score = 100;  
15:        _statistics.Time = DateTime.Now;  
16:        _statistics.PrintStatistics();        
17:        _statistics.LevelID = 2;  
18:        _statistics.Score = 200;  
19:        _statistics.Time = DateTime.Now;  
20:        _statistics.PrintStatistics();  
21:        _statistics.LevelID = 3;  
22:        _statistics.Score = 300;  
23:        _statistics.Time = DateTime.Now;  
24:        _statistics.PrintStatistics();  
25:        CareTaker.Instance.PlayerStaticsMemento = _statistics.CreateMemento(_statistics);        
26:        _statistics.LevelID = 4;  
27:        _statistics.Score = 350;  
28:        _statistics.Time = DateTime.Now;  
29:        _statistics.PrintStatistics();  
30:        Console.WriteLine("\nPlayer lost his life here so retore to level 3\n");        
31:        _statistics.SetMemento(CareTaker.Instance.PlayerStaticsMemento);  
32:        _statistics.PrintStatistics();  
33:        Console.ReadLine();  
34:      }  
35:    }  
36:  }  

UML Diagram :



Benefit & Examples:

1. Improve Performance:
      • Sine value calculation.

2. Undo/Roll back Operations:
      • Ctrl-Z in MS Word
      • Bank Transaction
      • Cancel operation in Forms

No comments:

Post a Comment