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