Lecture thumbnail 0:00 / 0:00 All right, so let’s see how we can use the memento pattern to implement, undo and redo functionality.
Now for this, what we’re going to do is we’re going to keep the mementos for all the transactions that
happen.
So all the invocations that happen in the bank account, we’re going to keep a memento for every single
one of them so that we can come back to any point in time.
So I’m going to make a private list of memento private list.
That’s weird.
Memento called changes.
And let’s just initialize it to a blank list.
And I’m also going to have an integer variable indicating the state that we’re currently in.
Because remember, if you do undo and redo, you want to be able to walk backwards as well as forwards.
So I’m going to have a private int current value, which is going to indicate which memento we are currently
on.
So in this case, when you initialize the bank account, not only do we set the balance, but we also
add the initial change.
And remember, that’s the issue or one of the issues which I mentioned in the previous example, that
there was no way of rolling back to the initial state.
Well, here it is possible.
So we can say changes dot add and we make a new memento with the current balance.
So that way we have at least one memento.
Now let’s go into the deposit method and let’s actually see how the deposit method will change as a
result of this approach.
So we’re still returning Memento.
That’s good enough.
But first of all, we need to keep it.
So we say var m equals new memento.
We add it to the list of changes.
So we say changes dot add, and we keep this memento in a list.
Then we increase the current variable because that points to the current memento, the memento that’s
kind of representing the system as it stands right now.
And then and only then do we return the memento to the client.
So this is how you would typically process the memento.
And then, of course, you have some sort of way of restoring the memento.
We have the method for this already.
Now I’m going to do a null check here, so I’m going to say m dot not null.
And the reason I’m doing this is because if you imagine yourself in a situation where you’re trying
to undo something, you’re trying to undo an operation, but there is nothing to undo, in that case,
the memento will return.
We’re going to be returning null and as a result, we’ll check for Null here.
Now, there are different ways of doing it.
You can return an optional memento.
You can, for example, return a memento which indicates the starting balance.
And that way you can always roll back to it.
I’m going to use Null.
I hope you’re okay with it.
So here, if the memento is not equal to null, we set the balance to the memento balance.
We add this memento to the set of changes.
So notice, even though I’m restoring to a particular state, what I’m doing is I’m also adding it as
the change in a list of changes.
Once again, it’s up to you whether you want to do this or whether you want to.
So the roll back to the mementos position somewhere in the set of Memento.
So, for example, you could go ahead and search for this memento in the list of changes and then roll
back to that particular index.
And in addition, what I do is I once again return the memento.
So the return type of this method also has to be memento, not void.
Now, if this fails, then I return null, because if I cannot restore Memento, then I cannot give
you a memento which kind of corresponds to the restoration.
So that is the restore process.
And now using this, we can also add the methods for undo and redo.
So those are very easy because what we’re going to be doing in the case of undo and redo is we’re going
to be manipulating current because current is effectively a pointer to a location inside the list of
changes.
So if we do undo, we just move it from the end, back towards the beginning.
And if we do redo, then we move current forward by decrementing and incrementing respectively.
So for example, if I want to implement undo, I have to say that I have to check.
First of all, the current is greater than zero, so we have some somewhere to undo this to.
Then I get the memento at the previous point.
So we say changes at minus, minus current.
So notice I’ve done two things at the same time.
I’ve decremented the current variable, thereby moving the pointer one step back.
So I’ve effectively done the undo operation, but I also acquired a change at this particular location.
Then I said the balance balance equals m dot balance here.
And then finally I return the memento.
And once again, if we don’t have anything to come back to, we return a null.
So here we return null.
And once again, the undo operation, like all the other operations, they return a memento.
So you have a way of coming back to this point, the point where you have undone something later on
and the same goes for redo so public.
Memento redo.
So here, if you’ve undone something, you can redo it.
Once again, we check the bounds.
So we say if current plus one is less than changes count, then yes, we can redo something.
Otherwise we’re probably at the last element anyway.
So we can’t really do anything.
We just return null.
But if we can redo, then once again we say var m equals changes at plus plus current.
So we move the pointer forward.
We set the balance to the memento balance and we return the memento as well.
So having made all of this, we can now try using this new approach.
So I’m still going to keep M one and M two, but in actual fact, let’s do it like this.
So we’re going to have a bank account with a 100.
I’m going to deposit.
I’m going to deposit 50, I will deposit 25, for example.
I will right line the bank account once again.
But this time around, what I can do is I can just start undoing and redoing those operations.
So I’ll say ba dot undo and I’ll write a line.
This time I’ll write line a bit more.
So I’m going to say undo one.
So this is my first undo and here is the bank account.
Then I’ll do undo again and I’ll copy this over and this is going to be undo two.
And finally I’ll do BA dot redo and I will once again copy this and say redo here, redo.
Okay, so let’s execute this and let’s see what we actually get.
So as you can see, we’re starting with a balance of 175.
Let me just move this over.
So we deposit 50 and 25 on top of 100, we get 175.
But if I undo the 25, then we end up with a balance of 150.
If I undo the 50, we end up with a balance of 100.
If I now redo the 50, we end up with a balance of 150 again.
So it works.
And this is how you can implement not just a way of rolling back to a particular state in the system,
but also allow for this navigation backwards and forwards by keeping a list of every possible change.
Play Play Stop Play Start Play information alert