Memento Pattern Code Review
Code Download
- Download Description:memento pattern download
- .NET Framework:3.5
- .NET Language:C#
- Date Published:2009-07-01
- Download Size:11 KB
Define the Memento Object
Define the Memento class (object) which is responsible for implementing the functionality to save and restore application state.
[Serializable]
class Memento
{
MemoryStream m_stream = new MemoryStream();
BinaryFormatter m_formatter = new BinaryFormatter();
public Object Restore()
{
this.m_stream.Seek(0, SeekOrigin.Begin);
Object o = this.m_formatter.Deserialize(this.m_stream);
this.m_stream.Close();
return (o);
}
public Memento Save(Object o)
{
this.m_formatter.Serialize(this.m_stream, o);
return this;
}
}
The application data is saved (serialized) into a binary format.
Define the Game, Caretaker and Simulator Objects
The Game class (object) represents the Originator component that generates the application data.
[Serializable]
class Game
{
private Char[] m_board = { 'X', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
public Char Player { get; set; }
public Game()
{
this.Player = 'X';
}
public void Play(Int32 pos)
{
this.m_board[pos] = this.Player;
if (this.Player == 'X')
{
this.Player = 'O';
}
else
{
this.Player = 'X';
}
this.m_board[0] = Player;
}
public Memento Save()
{
Memento memento = new Memento();
return memento.Save(this.m_board);
}
public void Restore(Memento memento)
{
this.m_board = (Char[])memento.Restore();
this.Player = this.m_board[0];
}
public void DisplayBoard()
{
Console.WriteLine();
for (Int32 i = 1; i <= 9; i+=3)
{
Console.WriteLine("{0} | {1} | {2}", this.m_board[i], this.m_board[i+1], this.m_board[i+2]);
if (i < 6) Console.WriteLine("---------");
}
}
}
The Game class (object) invokes the Save() and Restore() methods of the Memento class (object).
The Caretaker class (object) stores an instance of the Memento class (object).
class Caretaker
{
public Memento Memento { get; set; }
}
The Simulator class (object) stores the input data that is used by the Game class (object).
class Simulator : IEnumerable
{
String[] m_moves = { "5", "3", "1", "6", "9", "U-2", "9", "6", "4", "2", "7", "8", "Q" };
public IEnumerator GetEnumerator()
{
foreach (String element in this.m_moves)
{
yield return element;
}
}
}
Use the Memento Pattern
The Program class creates the Game object and an array of Caretaker objects.
class Program
{
static void Main(string[] args)
{
Int32 move;
Console.WriteLine("Let's practice TicTacToe");
Console.WriteLine("Commands are:\n1-9 for a position\nU-n where n is the number of moves to undo\nQ to end");
Game game = new Game();
Caretaker[] c = new Caretaker[10];
game.DisplayBoard();
move = 1;
Simulator simulator = new Simulator();
foreach (String command in simulator)
{
Console.WriteLine("\nMove {0} for {1}: {2}", move,game.Player,command);
if (command[0] == 'Q') break;
c[move] = new Caretaker();
c[move].Memento = game.Save();
if (command[0] == 'U')
{
Int32 back = Int32.Parse(command.Substring(2, 1));
if (move - back > 0)
{
game.Restore(c[move - back].Memento);
}
else
{
Console.WriteLine("Too many moves back");
}
move = move - back - 1;
}
else
{
game.Play(Int32.Parse(command.Substring(0, 1)));
}
game.DisplayBoard();
move++;
}
Console.WriteLine("Thanks for laying");
Console.Read();
}
}
Each Caretaker object will store an instance of the Memento object. The input data provided in the Simulator object is processed and
at the same time, application state is stored by the Memento object.