Memento Design Pattern in C#

Memento Design Pattern in C# with Examples

In this article, I am going to discuss the Memento Design Pattern in C# with examples. Please read our previous article where we discussed the Mediator Design Pattern in C# with examples. The Memento Design Pattern falls under the category of Behavioral Design Pattern. As part of this article, we are going to discuss the following pointers.

  1. What is the Memento Design Pattern?
  2. Understanding the Class Diagram of the Memento Design Pattern
  3. A real-time example of the Memento Design Pattern
  4. Implementation of Memento Design Pattern in C#.
  5. When to use the memento Design pattern in real-time applications?
What is the Memento Design Pattern?

The Memento Design Pattern is used to restore an object to its previous state. That means if you want to perform some kind of undo or rollback operation in your application then you need to use the Memento Design Pattern.

Understanding the Memento Design Pattern:

Let us understand the Memento Design Pattern with an example. Please have a look at the following image. As shown in the left-hand side of the image, we have an employee with Id =101, Name =John, Salary = 2Lakhs, Designation = Software Engineer, Address = London, and many more attributes. Later some point in time we did change some of the properties (Salary to 3Lakhs, Designation to Senior Software Engineer, like this we also change some other attributes) of employee which is shown in the right-hand side of the below image. That means we change the object state from State 1 to State 2.

Understanding the Memento Design Pattern

Later some point in time, we think that let’s undo or rollback the employee information to its previous state i.e. State 1. If this is your requirement then you need to use the Memento Design Pattern and rollback the employee information to its previous state.

Understanding the Class Diagram of the Memento Design Pattern:

Let us understand the class diagram and the different components involved in the Memento Design Pattern. In order to understand the class diagram please have a look at the following diagram. As you can see in the below image, there are three important classes (Originator, Memento, and Caretaker) involved in the memento design pattern. You can see the state in both Originator and Memento classes.

Understanding the Class Diagram of the Memento Design Pattern

The Originator class has two methods. One is CreateMemento and the other one is SetMemento. The SetMemento method accepts the memento object. So, what this Originator class will do is, it will instantiate the Memento object and set the internal state of the originator to memento state. So, basically what the originator will do is, it will take a snapshot of the originator and put it on the memento object. And that memento object will save into the Caretaker for later use.

Later use means, suppose at a later point of time, originator wants to restore its state then at that time it will take the old state from the caretaker and set it in the originator state so that the originator can restore its old state.

Originator: It creates a memento containing a snapshot of its current internal state and uses the memento to restore its internal state.

Memento: It holds the internal state of an Originator.

Caretaker: It is responsible for keeping the mementos. Like maintaining save points and never operates on or examine the contents of a memento.

If this is not clear at the moment, then don’t worry once we implement one programming example, so that you can easily understand this design pattern.

A real-time example of the Memento Design Pattern:

Let us first understand the example that we are going to implement using the Memento Design Pattern in C#.

I buy one 42inch led TV whose cost is 60000rs and it does not support USB and I placed it on the hall. After some point of time, I thought let buy 46inch led TV. So, I buy a 46 inch led TV whose cost is 80000rs and it supports USB and I want to place it in the hall. But already in the hall 42inch led tv is there. So, what I have to do is, I have to place the 42inch led TV in the storeroom and place this 46inch led TV on the hall.

Again after some point of time, I am thinking let buy 50inch led TV whose cost is 100000rs and supports USB. So, I buy this 46inch led TV and I want to place it in the hall. But in the hall, the 46inch led TV is there. So, what I have to do is, I have to take the 46inch led TV from the hall and put it again in the storeroom and then place the 50inch led TV in the hall.

After some point of time, I thought let put the 42inch led TV in the hall as the clarity of the 50inch led TV is not that good. So, what I have to do is, I have to take the 50inch led TV from the hall and put it on the storeroom and from the storeroom take thee 42inch led TV and put it on the hall. So, basically we are rollbacking to its previous state.

A real-time example of the Memento Design Pattern

In this example, the Hall is the Originator and the Store Room is the Caretaker. Led TV is the memento i.e. it used to hold the internal state of LED TV. This is one of the best examples of the memento design pattern. So, in a scenario like this, we need to use the Memento Design Pattern.

Implementation of Memento Design Pattern in C#:

Let us implement the LED TV Example that we just discussed using the Memento Design Pattern in C# step by step.

Step1: Creating LED TV

Create a class file with the name LEDTV and then copy and paste the following code in it. This LED TV class has three properties (i.e. Size, Price, and USBSupport) and we are initializing three attributes using the class constructor. This class also having a method called GetDetails which is used to return the details of a led TV.

namespace MementoDesignPattern
{
    public class LEDTV
    {
        public string Size { get; set; }
        public string Price { get; set; }
        public bool USBSupport { get; set; }

        public LEDTV(string Size, string Price, bool USBSupport)
        {
            this.Size = Size;
            this.Price = Price;
            this.USBSupport = USBSupport;
        }

        public string GetDetails()
        {
            return "LEDTV [Size=" + Size + ", Price=" + Price + ", USBSupport=" + USBSupport + "]";
        }
    }
}
Step2: Creating Memento

Create a class file with the name Memento and then copy and paste the following code in it. The Memento object is used to store the internal state of the originator. The originator has LED TV as an internal state and we are initializing that ledTV internal state using the constructor. This class has one method i.e. GetDetails which is used to return the internal state details of ledTV.

namespace MementoDesignPattern
{
   public class Memento
    {
        public LEDTV ledTV { get; set; }

        public Memento(LEDTV ledTV)
        {
            this.ledTV = ledTV;
        }

        public string GetDetails()
        {
            return "Memento [ledTV=" + ledTV.GetDetails() + "]";
        }
    }
}

Step3: Creating Caretaker

Create a class with the name Caretaker and then copy and paste the following code in it. This is nothing but the storeroom which is used to hold the led TVs. The caretaker is used to maintain the memento objects. This class is having two methods. The AddMemento method is used to add memento into the ledTvList properties and the GetMemento method is used to return the memento object.

using System;
using System.Collections.Generic;
namespace MementoDesignPattern
{
    public class Caretaker
    {
        private List<Memento> ledTvList = new List<Memento>();

        public void AddMemento(Memento m)
        {
            ledTvList.Add(m);
            Console.WriteLine("LED TV's snapshots Maintained by CareTaker :" + m.GetDetails());
        }

        public Memento GetMemento(int index)
        {
            return ledTvList[index];
        }
    }
}

Step4: Creating Originator

Create a class file with the name Originator and then copy and paste the following code in it. This is nothing but the Hall in our example where we need to place the led TV. Here, the CreateMemento method is used to set the internal state of the memento object to led tv. The SetMemento method and you have to pass the memento object to this method and this method is used to restore or rollback. From the memento object, it will get the internal state and assign that internal state to the originator’s internal state.

namespace MementoDesignPattern
{
    public class Originator
    {
        public LEDTV ledTV;
        
        public Memento CreateMemento()
        {
            return new Memento(ledTV);
        }

        public void SetMemento(Memento memento)
        {
            ledTV = memento.ledTV;
        }

        public string GetDetails()
        {
            return "Originator [ledTV=" + ledTV.GetDetails() + "]";
        }
    }
}

Step5: Client

Please modify the Main method as shown below. The following is used to explain the memento design pattern.

using System;
namespace MementoDesignPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            Originator originator = new Originator();
            originator.ledTV = new LEDTV("42 inch", "60000Rs", false);
            
            Caretaker caretaker = new Caretaker();
            caretaker.AddMemento(originator.CreateMemento());

            originator.ledTV = new LEDTV("46 inch", "80000Rs", true);           
            caretaker.AddMemento(originator.CreateMemento());

            originator.ledTV = new LEDTV("50 inch", "100000Rs", true);
            
            Console.WriteLine("\nOrignator current state : " + originator.GetDetails());

            Console.WriteLine("\nOriginator restoring to 42 inch LED TV");
            originator.ledTV = caretaker.GetMemento(0).ledTV;

            Console.WriteLine("\nOrignator current state : " + originator.GetDetails());
            Console.ReadKey();
        }
    }
}
Output:

Memento Design Pattern in C#

When to use the memento Design pattern in real-time applications?

In Real-time applications we need to use the Memento Design Pattern, when

  1. The state of an object needs to be saved and restored at a later time.
  2. The state of an object cannot be exposed directly by using an interface without exposing implementation.

In the next article, I am going to discuss the Dependency Injection Design Pattern in C# with examples. Here, in this article, I try to explain the Memento Design Pattern in C# step by step with an example. I hope you enjoy this Memento Design Pattern in C# with Examples article.

Leave a Reply

Your email address will not be published. Required fields are marked *