Design Patterns

Last Updated: 9/23/2024

Memento

  • Use for implementing undo mechanism

Classical Structure

Memento Classical Structure

Problem

  • Violates Single Responsibility Principle. Single Responsibility Principle means every class should have single responsibility. eg In restaurant, waiter is responsible only for taking order and not for cooking, billing etc.
  • Editor class has 2 responsibilities: State management, Editor features
public class Editor
{
    private string content = string.Empty;
    Stack<EditorState> prevStates = new Stack<EditorState>();

    public string Content { 
        get => content; 
        set {
            prevStates.Push(new EditorState(content));
            content = value;
        }
    }
    
    public void Restore()
    {
        var state = prevStates.Pop();
        content = state.Content;
    }
}
public class EditorState
{
    public string Content { get; init; }

    public EditorState(string content)
    {
        this.Content = content;
    }
}

public class Program 
{
	static void Main(string[] args) 
	{
		Editor editor = new Editor();
		editor.Content = "a";
		editor.Content = "b";
		editor.Content = "c";
		editor.Restore();
		editor.Restore();
		Console.WriteLine(editor.Content);
	}
}

Solution

  • Move state management from Editor to another class (History).
  • History class will be responsible for state management. Keep track of changes in state of editor
public class EditorState
{
    public string Content { get; init; }

    public EditorState(string content)
    {
        this.Content = content;
    }
}
public class History
{
    Stack<EditorState> states = new Stack<EditorState>();

    public void Push(EditorState state)
    {
        states.Push(state);
    }

    public EditorState Pop()
    {
        return states.Pop();
    }
}
public class Editor
{
    public string Content {  get; set; }

    public EditorState CreateState()
    {
        return new EditorState(Content);
    }

    public void Restore(EditorState state)
    {
        Content = state.Content;
    }
}
public class Program 
{
	static void Main(string[] args) 
	{
		Editor editor = new Editor();
		History history = new History();
		editor.Content = "a";
		history.Push(editor.CreateState());

		editor.Content = "b";
		history.Push(editor.CreateState());

		editor.Content = "c";
		editor.Restore(history.Pop());
		editor.Restore(history.Pop());

		Console.WriteLine(editor.Content);
	}
}

Example Structure

Memento Example Structure

Example Code