So this idea of keeping every single command that's been invoked on a bank account gives us interesting
possibilities.
One of those possibilities is to implement undo functionality so when you want to roll back one of these
commands you can actually get the code for it.
And the way this is done is by simply modifying the command so far we have just a single method called
Call and we can duplicate this and have a method called on do.
But of course in order to be able to undo something we need to be very careful because for example when
somebody tries to withdraw a certain amount but feels like we have if we go in here in the withdraw
like if somebody doesn't have enough money including the overdraft to actually make a withdrawal we
obviously don't want to undo that operation because that would be silly.
So let's see how we can actually go ahead and implement undo operation on a bank account.
And so a very naive implementation might look something like the following.
Let's suppose I decide to implement this particular function.
So once again what I'm going to do is I'm going to make a very silly assumption I'm going to assume
that the positive withdraw operations are symmetric.
So I'm going to try to undo a withdrawal operation by using a deposit operation and vice versa which
isn't really how you do this but never mind let's just do it for now.
So essentially what I'm going to do is I'm once again going to switch on the action that's being performed.
And here I will once again generate the switch cases because it's easier than writing them by hand obviously.
So let's generate those OK and then what I'm going to do is I'm going to say well if I want to undo
a deposit what I'm going to do is I'm going to say accounts to withdraw a particular amount and the
same goes in the other direction.
So for one to undo a withdrawal I'm going to do a count called the.
A set amount.
OK.
Now as you have probably guessed if the withdrawal didn't really succeed there is no point in depositing
the money because then somebody could cheat.
They could try to withdraw a million and then undo the operation which would cause a deposit of a million.
So what do you do in this case.
Well typically you have to break the open closed principle and unfortunately you have to go back into
your bank account and somehow modify it so that you know whether a change actually occurred.
So the simplest approach to this would be a kind of boolean flag to indicate whether that withdrawal
operation succeeded.
So if we go back into the bank account and we change the return type here to a boolean what we can now
do is if the operation succeeds we can return true.
And if the operation failed we can return false.
OK.
So this is a step in the right direction obviously and we can sort of generalize it.
We can go into the bank account command now and we can add a new flag indicating whether the operation
actually succeeded.
So here I can for example just add an ordinary flag or what I can do is I can propagate it up here because
we're all inheriting from command.
So I can add the boolean flag here.
So now what we would do inside the bank account itself is we would say that by default the operation
did not succeed
and we would only make it succeed by checking the appropriate flag when we actually Coale on the operation.
So here what we would do in the call is we would say account withdraw and we would assign it to succeed.
Of course if you do a deposit that always succeeds if you put in some money that always succeed.
So here we say succeeded equals true.
Now this way we can do is we have this flag and when we go to undo a particular operation what we basically
say if the operation didn't succeed then we boot.
So we say if not succeeded
then we simply return and we don't perform the undo operation.
So let's see how we can now process all of these operations and then undo them.
So here I have a bunch of commands that are being applied.
And let's see if we can undo them.
Obviously we have to undo them in the reverse order which isn't something we don't have a range based
for loop for doing that.
So I'm just going to have an ordinary for loop so I'll have the iterator STARTING AT commands dot r
begin iterator and I'll take two commands that are and plus plus iterator that's all that we need to
do.
And now instead of Commander call we do come and go on do.
And that is how you roll back the whole thing.
So we don't have any diagnostic output for the operation itself but it's going to trigger those supposedly
symmetric operations of withdrawing and deposit respectively.
So let's run this and let's see what we actually get here and now there is a bit of a problem here because
it's telling us the the command for the command doesn't have the operation that's because it's actually
the iterator and it has to be followed and because it's a pointer like so.
OK so we're good to go let's compile this and see what we get.
All right so here we go.
So the first three lines are the lines that we had where we apply the commands so we deposit a 100 and
withdraw 200 and then we perform the symmetric operations so to undo the withdrawal of 200 would deposit
200 and to undo the deposit of 100.
We withdrew all 100.
And the balance goes back all the way to zero.
So this is how you can use the command pattern to implement the undo operation.