Lecture thumbnail 0:00 / 0:00 So now we’re going to take a look at how to implement the Memento design pattern.
So the idea behind Memento is that you essentially provide an API which returns special tokens, and
those tokens are used to represent the state of the system at particular points in time.
And then you can use this token to feed it back into the system, to roll the system back to a particular
state.
So we’re going to look at two different implementations of Memento.
The first is going to be a very straightforward, very obvious kind of return to a particular state
which is encoded in the memento.
And the second one is going to be a more comprehensive undo redo framework.
So we’re going to use the example of the bank account that we’ve seen like 100 times before.
So we’re going to do this again.
So this time around we’re going to have a balance and we’re going to have a constructor which initializes
the balance, hopefully have to press this several times and then we’re going to have the deposit and
withdraw methods.
Well, let’s just keep the deposit method.
Let’s not worry about withdrawal.
But what we’re going to do is instead of making the deposit method void like we normally do, we’re
going to return a memento.
So what is a memento?
Well, a memento is quite simply, a token.
So we’re going to have a class called Memento here.
And this token can contain certain information about, let’s say, what state the system was in.
But we don’t really want users manipulating this information.
So we only want to let this information be encoded so that we can subsequently restore the system to
a particular state.
But we don’t want the user to actually interact with it.
So what I’m going to do is I’m going to make a public int balance property.
So notice the getter is public and we effectively have a private setter here.
So if we make a constructor, what this means is that you can make a memento, you can set the memento
balance using the constructor, but you cannot really change it because the setter is private.
So that’s exactly what we’re going to return from, let’s say the deposit method.
So here we’re going to say public memento deposit and we’re going to deposit a certain amount of money.
So what happens is we obviously increment the balance.
So we take the balance and we increase it by the amount.
But in addition, instead of having this method as void, what we do is we make a memento and we return
it.
So we return a new memento.
And the memento itself keeps the balance that we have set the account to at this particular point in
time.
So we specify the balance here.
So we’re returning a token effectively, which keeps the current balance, the balance after a particular
modification of the account, but it doesn’t let the user manipulate the account, it doesn’t let the
user manipulate itself as well.
So you cannot simply switch the balance to something else and feed it back into the system.
So now in addition to the typical methods like deposit, withdraw, transfer, whatever, what we add
to the account is an ability to restore the account state from this memento.
So we have a method called restore.
And this method actually takes a memento.
Memento.
And the idea here is very simple.
In our very trivial implementation, all we do is we take the balance and we set it to the balance of
the memento.
So notice you can get the balance of a memento.
You just can’t set it externally.
So that’s the idea.
Let’s generate a two string of some kind and I keep messing things up here, so I’m going to alt enter
generate and I’m generate formatting.
Members just want to output the bank account balance and then we can actually see how this memento is
supposed to work.
So the idea if we go into main, the idea is we make a bank account, var, var equals new bank account,
let’s say balance of $100, and then we’ll make a few deposits.
And for each of those deposits, we’re going to save the memento token.
So we’re going to say var m one equals bank account dot deposit and we’re going to deposit 50.
So the account balance should now be 150, and then we’re going to say var m two equals bank account
dot deposit and we’ll deposit 25.
So bank account balance should be 175.
Now I’m going to right line the bank account itself.
But here is the fun part.
So we’ve set the bank account, but now let’s suppose we want to roll back to a particular state.
And luckily we have the tokens for that state.
So we have M1 and M2, which can take us back to the state after a particular deposit operation was
successful.
So what I can do is I can restore to M one, so bank account dot restore to M one, and then I can write
line bar and then I can roll back to the latest state because M2 is the latest state that we have.
So bank account dot restore M2 and then write line bar once again.
Okay, So let’s go ahead and execute all of this and just see what kind of output we get from this.
All right.
So as you can see, we start out with a balance of 175 here.
That is the correct number.
Then we use the token M1 to roll back.
The transaction.
So we roll back to a state where we have 150 so M one preserves the state after the 50 has been deposited.
So we have 100 plus 50.
So we go back to 150 and then we roll back to M two, which is the latest state.
That’s when you deposit the 25 back and you get a balance of 175.
So you’ll notice that there are a few operational quirks here.
Like for example, you cannot roll back the bank account to the initial state, to the 100 because for
the constructor call you don’t get the token, you don’t get your memento that way.
And also, it is very inconvenient to have these tokens but not have a sequence of changes.
It would be nice if you could walk back and forward to the different states of the account like you
would if you had command pattern.
If you were doing command query separation, you would have a set of commands and you could sort of
replay those commands or undo those commands.
And we’re going to try doing something similar using the memento pattern in the next example.
So.
Play Stop Play Play Start Play information alert