Go Patterns

How to Implement Memento Pattern in Go

Behavioral Design Pattern in Go

Pavel Fokin
3 min readMay 16, 2022
Memento Pattern in Go

Let’s take a look at the problem. We have some object and we want to be able to save and restore its state. And we want to have a good design for it.

  • We want to have a separation of concerns, different logic has to have different owners.
  • We don’t want to break an encapsulation of the object and hide direct access to its state.

The Memento pattern is for the rescue!

Tasks

For example, we have a type that keeps a list of Tasks. We don't have direct access to the list of tasks, and we have implemented the Add method.

Tasks

Memento

As the first step, we will introduce a new type — Memento. This is the box that can keep a list of tasks. This list is also private and we have a specific method to access it.

Memento

The Memento object has to be as simple as possible and it doesn't have any other logic.

Improve Tasks

The next step will be improving the Tasks object. We'll need to implement two additional methods.

  • Memento() - it creates a Memento instance that keeps the current Tasks state.
  • Restore(m Memento) - this method can restore a Tasks' state from a Memento instance
Improve Tasks

History of Changes

The next object we implement will be a History type. This type keeps a stack of Memento objects.

Implementing this type is not required by the classical Memento pattern. But I think it’s good to have it for a cleaner example.

History

Usage Example

In this example, the main function knows why and when the Tasks need to save and restore itself.

In the general case, it can be an additional type that keeps that logic.

And output will be

# Output
➜ go-patterns git:(main) go run ./behavioral/memento
[Task 1 Task 2]
[Task 1]
[]

Conclusion

Implementation of a basic Memento Pattern is a good example of separation of concerns. It keeps encapsulation of the initial object and extends its functionality with new logic.

Happy coding!

Code examples can be found in my GitHub repo pavel-fokin/go-patterns.

More reading

If you like this article you can be interested in the following.

Originally published at https://pavelfokin.dev.

--

--