Save and restore the previous state of an object
Swift — Problems Catalogue #19
Problem Definition:
Consider the following scenario. You have to implement a video game 👾Players will take on the role of a hero, building up their strength and abilities as they progress through the game.
One of the key features of our game is the ability to save and load progress. We need a way for players to save their game at any point and then come back to it later to continue their adventure.
Problem Solution:
Solution —Memento it’s a behavioral design pattern that allows an object to save and restore its internal state without violating encapsulation.
Real-World Usage:
First, we need to define aGameSave
protocol that has two properties, player
and enemies
.This protocol defines the state of the player and enemies respectively.
The ConcreteGameSave
class is a concrete implementation of the GameSave
protocol, it has two private variables player
and enemies
which are set at initialization, this class holds the state of the game at a particular moment.
Next, we need a Player
class that represents the player of the game and has properties like name
, level
, health
, experience
, inventory
. It has two methods:
createGameSave()
method creates a new game save with the player's current state and enemies. This method is used to save the current state of the game.setGameSave(_:)
method sets the player's state and enemies to the state stored in the save passed as an argument. This method is used to restore the game to a previous state.
Afterwards, we need anEnemy
class that represents the enemies of the game and has properties like name
, level
, health
.
Then, we define aGame
class as a singleton that holds the enemies and the player. It has two methods save()
and load(_:)
that allows the player to save and load their progress respectively.
save()
method calls the createGameSave()
method on the player object to create a new save with the player's current state and enemies.
load(_:)
method takes a game save as an argument and calls the setGameSave(_:)
method on the player object to restore the player and enemies to the state stored in the save.
So, in practice, when the player wants to save their progress, the save()
method is called, this creates a new save with the current state of the player and enemies, and the game save is saved to be used later. When the player wants to load their progress, the load(_:)
method is called, it takes a game save as an argument and sets the player and enemies to the state stored in the save, restoring the game to the previous state.
This way the player can save their progress and restore it later without violating encapsulation. The player’s state is saved separately from the player object, so the player object can be restored to a previous state without having to know the details of how it was saved.
From this point on, the sky is the limit 🚀 well…almost.
Of course, this design pattern has its limitations but used in moderation, it’s a great tool in our development toolbox.
This is the next article in the Swift Problems Catalogue series in which I’ll tackle general software development problems. The aim is to have a quick reference guide that can be easily accessed when having a design/algorithm dillemma.
Let me know what you think and don’t be shy to share where and when this pattern simplified your coding experience 🎶