PHP Design patterns in Laravel - How Laravel uses them internally?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
here i have one laravel example app installed so let's find some design patterns in its source if you look at the code here in the index php we can see how this code runs it has some constant it has some maintenance mode included autoloader and then it has this app that's being made and this app then makes the kernel so this method is called make and it looks like a factory pattern and if it looks like a factory pattern and it smells like a factory pattern so it must be a factory pattern then if we go and into this make method here i will have to open this bootstrap app and inside this application if i were to search for the make method we can see that it is basically resolving a given type for from the controller but it will actually call the parent make and the parent of this app is the container and that make actually then resolves this abstract and abstract here it means that it's just a class name here that's the in index.php that we've seen this one the kernel class in our example meaning that it's not a concrete class it's a it's not an actual object but it's just a class name that's why it's called the abstract and here above we can see that it's either a string or even a callball the type of this abstract if we go into this resolve we can see some actual code happening some actual magic and by the way i'm not a larval expert i just use it when i need to and even then i read the documentation until i make it work but a lot of you guys asked me about where are design patterns used in some real code in some real application so i figured to go over some popular applications or some popular frameworks and see what i can make of it what we can find inside of it so if you see that i make some mistake please let me know in the comment and also i will not talk about using the laravel itself we can instead look at the source code itself on how the larval actually works under the hood and uh which pattern in you it utilizes so in future videos we can look into some other frameworks just write me a suggestion if you have some so if we open this resolve we can see that it's getting the alias for this abstract and that's fine it also fires some event before uh before resolving of any specific type and this firing of events that's the uh basically part of the observer design pattern or the subscriber publisher pattern where some other objects would basically subscribe to this event and then this event would fire on some strategic places and it will give to all its subscribers possibility to do some action before before the actual uh meet of this method is happening in this case resolving of the object but more about the observer a bit later here down here we can see the actual resolving of this singleton pattern so it checks if there is an uh instance like it says here in the source if there is instance already existing it will return it because then it's a singleton you will always get one a single object so it will not create a new one and a lot of people think that when an object is called a singleton it has to be a class with static functions and has to keep its own instance but that's not always the case a singleton means that there can only be one class or one object of its kind in a run time of the application in java that will be the lifetime of the application but since a php has one runtime per http call that's what we call a singleton in php that's the closest we can get and even though technically php cannot have a true singleton like java because again php script basically ends once it's resolved when it's response to the client so for the next request a new object is created thus not exactly a singleton and this get concrete method here would give us a concrete reference from this abstract class name so i'm also wondering if there is a strategy pattern here as well because it will give you some existing concrete object from its storage or it will make a new one based on some parameters and that's uh somewhat a strategy pattern to decide which type of object you need to use but here since it's the same type it might not be there or maybe it isn't a variation of it but this is buildable here is actually checking if it needs to create nested dependencies and that is also one thing that factory pattern does it basically makes creating complex objects easier imagine you have to resolve all related objects each time you need a class it would be just a pain to work with if you work with laravel it has an object with an object within an object and it can do that basically indefinitely or in nested like that in a lot of steps that would be very difficult to build on your own that's why we have the factory here that will build that for us and it will also do a lot a lot of things along the way but at the end it will basically return this object for us it will also raise some events but once this object is returned we can get it back here inside of our index php so the purpose of the factory pattern or the problem it tries to solve is about creating complex objects like in this example but it can also work with solving the problem of making a decision between which object type to use here in laravel our factory is making us a concrete object out of the abstract representation of it or a string for example but it could be used to decide which type which is the appropriate object type it should return back say for example you need a proper shipping provider for your product if some products from your stores needs a special treatment like for example a large tv so instead of writing a bunch of if else's in your controllers in all the places where we need to figure out which shipping provider to use we can just provide our factory with the product as a parameter and it will construct and give us back the appropriate shipping provider for that particular product in that way we have the deciding logic of which object type to create but the same goes for complex creation of objects just like in our case here and by the way these slides are from my course check the link in the description so for this first line we already mentioned several design patterns so let's continue with the next line and that is this kernel handle which handles some requests and if we open this kernel class and that one is here in the foundation http kernel here we can find this handle method as we can see that it tries to handle the request right but at the end of the car of the handling it actually dispatches a request handler handled event and this is the same or a similar thing that we noticed before if you remember in our container here on the fire before resolving callbacks and also down here fire resolving callbacks it's basically the similar thing now they are implemented in different waves uh ways these are callbacks and these here in the kernel are actual objects that are being dispatched or the events but they both look like and they both smell like the observer pattern and the observer pattern has two parts the subject and the observer and subject in our case would be this very kernel because that's something that's being observed by the observer and even more closely we can even say that or it's more accurately probably that this request handled is the subject because that's is what we would look at that is something that we will subscribe to if there is an event of this type request handled we can do something on that and if we even if we try to do that if if in our application in our app providers in the event service provider here in the boot method if we would to put one event and listen and this listener needs a function and that function needs basically the event that we are going to observe in our case that's request handled right we can do something for example we can uh dump and die that request has been handled now if i would to run our app i will just run it from the console here we can see that it will actually stop when this request has been handled because well there is an event that happened of type request handled right and it will stop here where we tell it to do now this here give us the opportunity to modify these requests to react to it to do some modification or to do something entirely else when we are handling some requests now the observer design pattern itself is used a lot in laravel and pretty much every other application or framework that's that's a bit larger especially if it supports plugins because it's a great way of extending the native functionality without the need to change the source code of the application itself it's also known as publish subscribe or it's a variant of it and it's a behavioral pattern it's mostly used for having objects react to some events maybe to some changes most likely some other objects but without direct connection between those objects in code meaning without creating any dependencies between those objects that are related this is very powerful and using this method or this pattern creates pretty much the most isolated code you can have and thus makes your application very scalable and easy to expand as in our example we didn't need to touch something in the kernel right we still know when the request has been handled and we are still able to do something once that happens in application life cycle and we can do a lot of things in this place stop the application for working or manipulate the request or the response itself all that without changing the core code of duplication itself when we update our app later to the new version of laravel for example this and this kernel file gets changed our code would be overwritten if we had to change it but this code here that we have written now it will still listen to that event and it will still work fine regardless of how the the kernel works itself and this portion of code here this dispatch here it looks like a dependency injection it smells like a dependency injection but it's not really a dependency injection and i'll show you why this is something that i misunderstood when i started learning design patterns years ago and i see a lot of people struggle to notice the difference between dependency injection and a plain simple method with parameters passed when we look at this dispatch we can see that we are injecting some object into this method into this dispatch in the events right and again that looks like dependency injection and what it does it gives some class to another class because the another class needs that to operate it so this will this dispatch will dispatch the event right but it can in practice dispatch pretty much any event without knowing which event it works with if we look at this dispatch method and it's here in the events in the illuminate events dispatcher if we look for the dispatch we can see that it will fire an event and call the listeners right but we also see that this event can either be an object but can also be a string and this event dispatcher will then parse events and payloads and it should broadcast some events it will get all the listeners and it will get the response back the response of the action itself and in this particular example this event can be of any type right as we as we talked about it can be a string it could be an object and that is because this dispatcher basically does not depend on this event it's just passes it to the listeners and that's it it doesn't use any of its uh values it can be an empty string as far as this dispatch this dispatcher is concerned right so it doesn't depend on it actually if this dispatcher had for example some here code that says event and then call something then we can say that this is a dependency ejection because it would depend on this event being of some particular type maybe or having this call something method on it it would have to conform to some interface to some agreement between these classes but right now without this it basically does not care what it what this event is so in this particular case this dispatch is just a regular function regular method this dispatcher does not depend on input for this method if we look at the constructor for this dispatcher however we see that it actually expects some container here so it expects some particular object of some particular type container contract in this case however one of the quirks is that it can also be a null here which means that it will be created a new container will be created if you don't provide it anything so it does depend on this container but at the same time you can provide null and it will create a container for itself this would be a hard dependency because this dispatcher cannot be made without this container right but since there is uh this new container here immediately it's sort of a cheating to the dependency injection or it's not dependence injection at all this kernel however that we looked at her earlier if you look at its constructor we can see that we have to give it a concrete application so it's not an abstract application class name or a string it has to be an object that conforms to the application interface and the same goes for router and it needs this value to operate with so it does some calls on this application if we search throughout this code we can see that this application needs to have some events there is no check if defined on the events or something like that the same here this app instance it knows that this instance method has to exist in this app and that's all being determined here by this contract between this kernel and other objects so this application has to be the type of application and this router has to be the type of router it has to conform to these types that are being given here so this contract foundation application must exist and must be here and this is the example of hard dependency injection we know that this kernel needs to have this application properly configured and already created and the same goes for router in order for this kernel to work with right and that is basically the whole point of the dependency injection and that's basically the whole point of dependency injection it will make sure that each object gets its dependencies and laravel is generally quite loose when it comes to data it works with unlike the zen framework for example which i think is much more strictly defined but this is a dependency injection meaning that we need to provide all created and configure objects to some particular class in our case kernel needs application and the router because it cannot operate without them however our application could run from browser for example using http routing but it could also run from the console and then it would need a different strategy or a different application altogether and larval actually has a different kernel for this that's not inside the http and which kernel is being run that depends sort of on a strategy but the dependency injection keeps the kernel clean from dealing with creation of the actual application in the router it will just work with the kernel things and it will get those dependencies already configured and speaking of things that seem to be something but are not here in the dispatcher while we were looking at the previous methods i noticed this arraywrap static method which basically just wraps the value of the payload and a lot of people see this syntax for the static method and then ask me why is the singleton used there now this is a static method which does not mean that this is a singleton a singleton can have a static method and a static method can be without singletons right now the default way of creating a singleton class or a singleton object in php is this the static method sorry so people immediately assume that static functions are or are used as singletons and if we try to make one this error object so if we open our web we can actually open one route let's use the home route right and give it some function and here we can just try to make one object using the r support method right sorry the new and if we try to make one more support our method uh sorry our object we can actually see that everything will work fine if i would just run now this index.php from the console again we can see that everything is fine there's no complaints and if we actually try to compare this app on the using the compare by reference with three equals we can basically uh dump and die saying that these are equal or we can say that else if they are not equal we should say not equal if i were to run this index.php again we can see that they are actually not equal because this comparison is by reference meaning that these two objects are not the same which means that this is not a singleton that's the easiest way to check if it's a singleton and the fact that we can even create an object by using the new means that it's not a singleton it means that it's not protected from creating new objects so this is just a static method it's a helper that allows us to manipulate the array by wrapping it or by sorting it or by finding something etc etc there's a lot of cool classes that will sorry cool methods that will help you with working with arrays but as we've proven it's never intended to be a singleton and it's never actually used by an object and we did mention a true singleton before here inside of our container where we are checking whether the instance already exists whether it's being managed as a single tone so we can see that it if it's in singleton if it exists inside of this instances array it will be returned and the same here if it is a type of that should be made as an instance that's probably this needs contextual building it will then be stored inside of this instance property the first time app runs and then later you will always get the exact same instance which means that it will not be created again and that's also again the point of the factory pattern it will know which type of object to return whether to make a new one for you or to give you the existing one and it will also resolve all those objects as we discussed before and fun fact if you don't know it each new line for comments is three letters shorter than the previous one and that's something that larval or tyler actually do when they're writing the source code but the whole point is that we can make a singleton without using these static methods we can make it using the factory pattern right if we were to make a singleton without the factory then we need to use the static methods to do some actions or we don't actually need to use static methods to do the actions but we need them to make the object that will be stored in the class itself as the instance of the object so what we do when we need to prevent making new objects is usually making the constructor private and we would need also to prevent cloning and waking up or deserializing the objects and we will need a controlled place on when and how to initiate that single object itself and that will make it so that whoever is consumer of our class or our objects we always get a single object as in this example for the database here all our objects will always get the exact same connection to the database because we obviously don't want to open a connection to a database for every new object that's an expensive operation and they don't need the separate database connections without only one connection to exist for our runtime and the only place i was able to find a traditional singleton laravel is here inside this illuminate where was it in foundation and inside of this alias loader and here we can see all the things that identify the singleton first we have this instance being stored inside the class itself we see that the constructor is being made private which means that we cannot initiate this alias loader one more time we cannot even make a new object out of it and we can also see that it has the get instance method and here at the end it has the clone overwritten as a private meaning that you cannot clone it so before we summarize what we've seen here i encourage you to dig a bit on your own in the source of larval or pretty much any framework or application that you're using just try to understand what's going on with your data how is it passed between the objects as that way you can find some cool solutions and tips on how the your application is actually working and also maybe consider checking out my practical php design patterns course where we go over the most popular design patterns and look at how to use them in real life problems and real-life projects so we now went over three lines of larval code in our index php here and we saw that it has like four or was it six design patterns we've seen that the factory is used for making complex objects as well as determining which object you should get we've seen how the observer is used to publish and react to some events and keep your classes and even modules very separate so that they don't know about each other we also looked at how dependency injection separates objects from its dependencies and making sure that they have those dependencies right that's the name and we also talked about how singleton has to be a single class or a single object instance it doesn't have to have the static methods it could be made using the factory to make your services as long as you get one and only one object reference in the actual memory reference that is a singleton you'll also see in how you can combine multiple design patterns like the factory to make the single tone because a lot of people are confused as to where should you use one or the other it's not only one or the other they can work very well together if you have any questions please let me know that's all for now bye [Music] you
Info
Channel: Applicable Programming
Views: 355
Rating: undefined out of 5
Keywords: programming, web development, tutorial, php oop project, php design patterns interview questions, php design patterns, php design patterns tutorial, design patterns php, advanced php, design patterns, php interview questions and answers, why design patterns, why design patterns are important, why design patterns in c#, design patterns explained, design patterns software engineering, design patterns tutorial, software design patterns, why learn design patterns
Id: wHrkL2SKjjk
Channel Id: undefined
Length: 22min 16sec (1336 seconds)
Published: Mon Dec 13 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.