Narrator: The problem we have
with processPayment and processRefund is
that we have some kind of code duplication in there.
We have the same kind of checks, which we run in there
and that's bad because that means
that we repeat ourselves, which we of course shouldn't do
as we learned.
The problem just is that
for these different checks, we then do different things.
We processCreditCardPayments
and CreditCardRefunds, which are different functions
which of course that should be easy to imagine,
do totally different things in reality.
Here, we just log something
to the console, but that's just some dummy code.
In reality,
there's a big difference between charging a credit card
and refunding a payment to the credit card.
So it makes sense that we have different functions here
and we probably won't be able to merge these
in an elegant way.
Though there actually is something we could
consider doing to slim this code
down and to make it more readable.
We could kind of inverse our checking logic.
Now, what do I mean by that?
Currently we first check whether we have a payment
or a refund, and then we process this payment
or a refund, which means we then have these checks.
Of course we could theoretically
also first check what the payment method is,
since we have the same methods for both payments
and refunds, and then only check if it's a payment or refund
in the second step. To check this, I will actually get rid
of checking for his payment and his refund, though,
I will keep these functions
but instead I'll add a new function where I wanna check
whether a transaction uses credit card, PayPal
or a payment plan.
So we can name this function usesCreditCard
and we would get a transaction here.
And then I wanna essentially return this check here.
So I have return transaction method equals credit card
and we can repeat this function to
also have a usesPayPal function, where we check
for PayPal as a method and to have a usesPlan function
where we check for plan as a payment method.
We could even merge these together
and just have a usesTransactionMethod function
where we get the transaction and the method.
And we then have this comparison here.
It's up to you,
which approach you prefer. With such a method added though,
we could go to processTransaction
and not check first, whether it's a payment
or a refund, but instead, simply check
if he usesTransactionMethod
for any given transaction.
For example, if we use credit card,
and if we do that, then we'll do something here.
Else, if we use the another method
let's say PayPal, we do something else.
And last but not least
if we have a transaction where the method is plan,
we do get something else.
Now, what are these something else's which you wanna do?
Well, that is now our processing
for credit card transactions,
PayPal transactions, and plan transactions.
So these would be new functions, which we can add.
We can add a new function here, maybe above processPayment
which is named processCreditCardTransaction.
And here we get our transaction, no matter
if it's a payment or a refund and we can do the same
for PayPal to have a processPayPalTransaction
and the same for a payment plan.
So processPlanTransaction
and we'll add logic to these functions in a second.
So now we have these free functions
and these are the functions which we wanna call here.
So we wanna process a credit card transaction here
and forward the transaction in the next
if branch, we wanna processPayPalTransaction
and forward the transaction.
And in the last branch, we wanna processPlanTransaction
and forward the transaction like this.
Now we will eventually remove this code.
I'll just leave it here for reference for a second.
But now we have these functions
which are being called depending on the transaction method.
So to check, which we previously had instead
of processPayment and processRefund now moved
up one level directly into processTransaction.
Therefore, to fully invert our logic,
we now have to move the payment
and refund logic down one level
out of processTransaction into these processCreditCard,
PayPal and planTransaction functions.
Hence now in all these functions,
we have to check whether we have a payment or a refund.
And that is what I meant with, we invert the logic.
We will still have some duplication.
There is no way
around that because we had two dependent kind if checks.
But now we have the more complex
if check where we replicated three different checks
at a higher level.
And we have the easier check where
we only have queue options at a lower level.
But on the other hand,
we execute this check three times now.
So overall, we can question whether we gain a lot.
Nonetheless, let's finish this before we look for an
even more elegant solution.
So here, in processCreditCardTransaction, we can now check
if we have a payment using this is payment function
which we defined before,
for our given transaction, or if we have a refund
for this given transaction or else we know it's invalid
and then we can show an error message
and simply, well, use this code
from before, show error message, invalid transaction type
and pass the transaction as well, like this.
And now,
if it's a payment, we know it's a credit card payment.
So here we can call processCreditCardPayment.
And that's one
of the functions which existed right from the start.
One of these dummy functions.
If it's a refund, we know it's a credit card refund,
so we can call processCreditCardRefund.
And now we can copy that code
into the other method functions here.
So here we call processPayPalPayment
and processPayPalRefund.
And here we have processPlanPayment
and processPlanRefund.
And we can now get rid
of processPayment and processRefund down there
because we don't need these functions anymore.
So what we did now is we inverted these checks.
Now we check for the method
at a higher level, and then for the type of transaction
at a lower level, hence we can now remove this
if check here from the process transaction function
because that's the check which we now have
in all these methods, specific functions.
Nonetheless, of course we have duplication here
and just like this, we also won't be able to get rid
of it because we're in the interest of moving around checks.
And it's up to you,
which kind of solution you find easier to read.
If it was the one from before
where we had the payment refund check at a higher level
and we checked for the method at a lower level,
or if it's this solution where we do the opposite.
Nonetheless, this is our current state
which we will now use to build up on.