Without violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.
This pattern is used to save the internal state of an object when it changes state of over the time. You can use save points when you save the state so that you can retrieve the state of the object
This is the UML diagram to show the Memento Design Pattern
Now we will see the participant in the UML diagram
Originator
Memento
CareTaker
To understand the memento design pattern completely we will code one example using VB.NET
You have Game class to hold the score of two teams. when they are playing you can store the score with save point so that you can undo using save points.
You can have a look at the UML diagram of the following example
To implement the above example I have used following code
Game Class (Originator)
In this Originator we have the scores of Team A and Team B also we have reference to GameCareTaker object
Public Class Game Private m_TeamAScore As Integer Private m_GameCareTaker As GameCareTaker Public Property TeamAScore() As Integer Get Return m_TeamAScore End Get Set(ByVal value As Integer) m_TeamAScore = value End Set End Property Private m_TeamBScore As Integer Public Property TeamBScore() As Integer Get Return m_TeamBScore End Get Set(ByVal value As Integer) m_TeamBScore = value End Set End Property Sub New(ByVal teamAScore As String, ByVal teamBScore As String, ByVal ct As GameCareTaker) m_TeamAScore = teamAScore m_TeamBScore = teamBScore m_GameCareTaker = ct End Sub Public Sub CreateSavePoint(savePoint As String) m_GameCareTaker.saveMemento(savePoint, New GameMemento(Me.TeamAScore, Me.TeamBScore)) End Sub Public Sub Undo(savePoint As String) Dim memento = m_GameCareTaker.GetMemeto(savePoint) Me.TeamAScore = memento.TeamAScore Me.TeamBScore = memento.TeamBScore End Sub End Class
GameMemento Class (Memento)
This is our Memento class and it has same properties like originator class
Public Class GameMemento Private m_TeamAScore As String Public Property TeamAScore() As String Get Return m_TeamAScore End Get Set(ByVal value As String) m_TeamAScore = value End Set End Property Private m_TeamBScore As String Public Property TeamBScore() As String Get Return m_TeamBScore End Get Set(ByVal value As String) m_TeamBScore = value End Set End Property Sub New(ByVal teamAScore As String, ByVal teamBScore As String) m_TeamAScore = teamAScore m_TeamBScore = teamBScore End Sub End Class
GameCareTaker Class (CareTaker)
This is our CareTaker class. This will save the Memeto and retrive the Memnto once you give the save point details
Public Class GameCareTaker Dim htScore As New Hashtable() Public Sub SaveMemento(ByVal savepoint As String, memento As GameMemento) htScore.Add(savepoint, memento) End Sub Public Function GetMemeto(ByVal savepoint As String) As GameMemento Return DirectCast(htScore.Item(savepoint), GameMemento) End Function End Class
This is the Client program to test the design pattern
Module Module1 Sub Main() Dim careTaker As New GameCareTaker() Dim tennis As New Game(0, 0, careTaker) 'set score tennis.TeamAScore = 0 tennis.TeamBScore = 1 tennis.CreateSavePoint("Save Point 1") tennis.TeamAScore = 0 tennis.TeamBScore = 2 tennis.CreateSavePoint("Save Point 2") 'Undo tennis.Undo("Save Point 1") Console.WriteLine("Team Score :" + tennis.TeamAScore.ToString() + "/" + tennis.TeamBScore.ToString()) Console.ReadLine() End Sub End Module
Output of the above Example
Team Score :0/1