Okay, so finally, let's add the missing implementation for those abstract methods in a stripe processor
class.
And then the PayPal processor class.
Now those are really dumb implementations.
They just echo something so that we know that methods were called.
And the actual implementation of those is not something that is bothering us right now.
Okay.
I think now we should see how we use all of those processor classes.
So to illustrate those examples, we're going to create yet another class.
But we are not going to write it on screen.
I'm just gonna quickly make it from some building blocks using some of my editing magic.
So the class in question is an order processor.
So that's a class that is responsible for processing some user orders.
Let's imagine that is an e-commerce system.
So this order processor a part of performing its duties with regards to whatever needs to be done when
order is made.
It's going to accept a payment processor.
So this means that the order processor can work with any of the payment processors that we have stripe,
PayPal or cash.
We additionally get a runtime polymorphism.
So this means we can change the payment processor at Runtime.
It doesn't have to be predefined.
When you create an order processor, you can then choose maybe depending on some conditions or selected
payment processor which one to use.
Now generally this technique that we've seen here.
So passing an object by constructor or through constructor this is important because this is called
composition Teeths.
Now it is a very important technique.
And a lot of people a lot of software developers prefer composition over inheritance.
This means that passing classes around that can have some specific functionality is preferred to extending
base classes to add more functionality to the base class, and I agree with that.
Now there are some obvious cases for inheritance.
Like we've seen right here where we defined an abstract class which had some base functionality.
Specific to online payment processor.
But that's a specific case.
And those specific cases.
Make sense to use inheritance.
But generally I also think and I agree with most developers.
That you should heavily rely on composition.
So passing around objects that provide certain functionality.
And if additionally those.
Objects implement interfaces, you've got much more benefits like loose coupling.
That's another term you can remember.
Member.
This means that the order processor isn't really tightly coupled with any specific payment implementation.
It can accept anything that can adhere to this specific interface contract.
And additionally, composition gives you possibilities for easier testing because it will be much easier
to unit test by providing mocks for this specific interface than creating or using some actual implementation.
So we are doing some of the software engineering best practices in here.
So next up this class is getting a process order method which needs to do something, whatever that
is.
We're not going to go into details.
And finally it's using the past payment processor to process the payment, and it is logging whether
this was a success or not.
And this also gets a refund order method.
So this is our order processor class.
Now finally it's time to have a complete demo.
So let's start with the stripe processor.
Then let's add a PayPal processor.
And finally let's create a cash processor.
Then we are creating separate instances of an order processor class which have different payment processors.
And finally let's process some orders.
So if I run this now well we have an error somewhere.
So stripe processing was fine as we see.
But there was a fatal error invalid API key in line 27.
That's an online payment processor for 150.
So we do that with PayPal.
So apparently I must have passed a key that's too long.
So this is actually 34 characters.
Okay.
Let's quickly fix that.
This should be 32 characters.
That's what that was the requirement for PayPal processor.
And now it seems like everything is fine because we get the messages from stripe, from PayPal and all
the info that things were processed successfully.
So whether this logic functions properly is not as important because that's basically dummy logic everywhere.
And the last three videos were mostly about the software design.
So about the interfaces and their purpose, about abstract classes and abstract methods and all those
either design patterns or software engineering keywords that I think that a good developer should know
or at least be a little bit familiar with, because in the future, if you'd like to work with any kind
of a framework like Laravel or Symphony or any other PHP based software, you might and you will definitely
will encounter all of those designs and keywords and best practices.