PHP Design Patterns course preview - PHP Dependency injection and factory pattern -Advanced OOP PHP

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
design patterns help us really understand and use object-oriented principles correctly it's not enough learning to make a class and a object from it that's the easy part the difficult part for me at least was using objects efficiently and have the communication between the objects efficiently and easy to maintain and also avoiding all the mistakes of the messy code if you read about design patterns before but you're still not feeling like you're using them in everyday coding or maybe you started working with some framework and everything looks a bit unnecessary complex i've also noticed a lot of people struggling with understanding object oriented programming and also design patterns and i personally believe this has to do with way too abstract examples on the internet the typical car and animal problem and i've been working with php for 15 years professionally and i've never encountered those type of objects in real life that is why i made a course about design patterns in php that i want to show you a preview of and in this course i go over the real life examples we go over most popular patterns in applications like cms or e-commerce webshops on popular frameworks we use the most popular services like shipping and payment and email and things like that the the things that our clients will actually pay us to work for so no cars or no animals we showed the problem the each pattern tries to solve we then explain the theory of that pattern we solve our problem and then we look at some of the popular use cases in different framework or e-commerce or cms application there is also homework so that you can practice and learn them this course will help you go from junior to or mid level to a senior much much faster at the end you will be able to confidently use classes properly recognize when to use each design pattern and know what their advantages and trade-offs are you will also avoid common traps that lead to a messy code when using objects and my personal goal is to make this course the only resource you will ever need for design patterns in php and you get a lifetime access to it i'm constantly adding content to the course and all future updates to this course like new modules videos ebooks practicing materials pretty much everything is included in your purchase today and that way you have everything on one place when it comes to design patterns and more however i am still making this course and in the description there is a link with a coupon that will give you a huge discount as an early supporter coupon is however limited by number of people and by the date so please use it while it's active so here are some lessons from the course and i hope you like them so design patterns are solutions to common problems are mostly focused on working with objects they're like a recipe for common problems that people encounter with objects you can imagine some sort of common problems of course that look similar and you would fix those problems with some particular pattern depending on what the problem is right design patterns improve interaction and communication between objects in our code and they help us build reusable and easily extensible software by preventing us from making some code mess or dependencies and making some difficult way of sharing data between objects so they are similar to a cookbook of recipes for the most popular dishes so a proven way of doing things like making food however a design pattern is not a particular piece of code that will solve all of our problems it is more a way of thinking when approaching some problem so that you can come with a solution yourself some problem they solve how to use multiple external libraries for example like different payment providers and all that without changing our existing code in our application or how to adapt some for example external api or how to adapt a third party library to our code maybe with the code organization code readability etc so they keep our code better organized for example by avoiding dependency between classes or they reduce code application and they give us centralized place for business logic etc and when i started actively thinking about using design patterns in my code besides the more readable code of course i noticed a very positive change in my career and the way co-workers started working with me because i could communicate things much better and find better solutions by just thinking about does this look like a familiar problem that a design pattern might solve and once again design patterns are not very concerned with the concrete implementation in a sense that your code will run faster or be more secure by writing this or that or this function or that function they are concerned with speed of development and price of maintenance making it faster for you to make code that is easy to maintain later and reduce the number of errors that you can make along the way because again they solve a lot of problems that people have observed already with object oriented code and solved it already in general design patterns are organized in three groups creation of structural behavior however i think that coding along and showing the real life examples is much more important than all the theory around this pattern so i organized the code and this entire course in such a way that it's easy to understand and follow rather than it being just an alphabetical list of patterns that you will most likely never go over and never finish they're also kind of ordered by priority or should i say their popularity so you can follow but you can also jump around and watch what is interesting for you at that particular moment but more about course organization in the next video [Music] dependency injection was my personal aha moment when it comes to the good and clean object-oriented code and if you learn only one thing from this course i would like it to be this pattern because it's that powerful it is called dependency injection because we are basically injecting a dependency into a class so instead of a class picking things it needs from the application we are going to provide to the class what it needs this way of thinking in a reverse sort of is perhaps most difficult if you are used to procedural programming where inside the function we would most likely reach out to get other resources here we are injecting class dependencies from outside of the class and providing it to the class and when i say dependency i'm referring to any other resource a class might need and depend on one typical example is a database connection so instead of a class making or requiring database connection manually like it would do in our previous singleton pattern we would actually give our class the database connection it should use so we are separating the class functionality from its dependencies we are keeping the class clean the class does not need to know which database connection it uses it should focus only on its own functionality instead other typical examples are email provider the logger the different services pretty much every class that could be used in some other class again very similar to singleton example mostly the service classes and some configuration and advantages of using dependency injection over singleton is that we have much better control over what resources our classes are using because again we are the one deciding what our class should use from our controller this way also our class is decoupled and it is now not worrying about getting its own resources thus we are keeping scope of that class much cleaner and most importantly we are implementing that single responsibility principle with our classes because now they are only focused on their own duties and their own functionalities and since our class is now working with whatever we are providing it testing of our class is much easier because we can give it the fake email the in-memory database the fake shipping provider the testing database and it will work it should just not care whether the email is actually being sent or whether the database connection is being established it has only one duty right it also means that we can reuse our class much easier on other places or perhaps the entirely different projects and it will continue working as expected as long as we provide it with needed dependencies and almost nothing comes without disadvantages so here we need to know how to properly construct the object our class wishes to use so we need to set up all of our dependencies properly so that the resources are properly set and the factory pattern helps us here and we'll look at that pattern in the next module and we can also use the interfaces to help us with what should be provided to the class however it is a still thing to consider another challenge is actually knowing where those dependencies are coming from especially if you're not familiar with the entire code base and all the inners of your project like if you're using some new framework or some new project that you're not that familiar with at some point you sort of need a entire structure that will help you track all dependencies and construct them properly and then inject them and this can easily introduce a lot of code inside for example a controller if you're just doing the initiation of an object there and since it is very popular dependency injection is used pretty much in any serious framework laravel uses it via its service container the symphony has a dependency injection component and many others use it and we can inject dependencies uh while constructing the class this is to make absolutely sure that the class is constructed properly for example if we are writing a email formatter class that would usually depend on some let's say mailer transport class so this is called a hard dependency which means that our mailer format class cannot even be initiated without the class it is depending on and we can also inject dependencies later during the run time and this is called soft dependency and we would inject them via some method like set formatting provider for example where we would pass independency that this class needs in that particular use case during the execution of our code and this is often used when we have really complex classes that do a lot of things or perhaps a library that can do several complex things like image manipulation for example here we might not always want to crop and resize and change the color of the image we would rather pass dependencies based on the actions that we want our class to do in that particular case i'll show you the example of the popular imaging library that uses dependency injection very well but in it we would set a object that will determine the size or the crop mode or the color mode and then we would pass that object as a dependency to the class but only when we are going to actually do the cropping or changing of color in this case having all dependencies required and the initiation of the class does not make sense because the class can be used in multiple different scenarios so similar to the singleton pattern we discussed in the previous module these classes also have some dependencies so here for example we are sending an email and then redirecting it so we are getting all administrator emails and we are sending the emails notification to all the admins now these classes here the user and the email they both require database so they initialize the database here and also here and then they do what they need to do they send email they save the notification to the database maybe they save the log etc and here we can see that these classes the email and the user have their own dependencies they cannot work without this database so these classes need to create a database connection and in this particular case this is uh relatively easy and trivial but in more complex objects there is a lot more to that needs to be configured inside the classes then for example in the email we might want to log this email and also this email for example might need a different email driver if we should use like for example mail gun or google smtp or multiple instances of different mailers and each of these services have a different way of connecting to its appropriate services different ways of working however our email class should not care about the transfer it should send the email whichever driver we provide it so here it would then have to initialize the correct driver set all the connection parameters or perhaps even store the usernames and passwords and everything and that is a big mess then when we have things to change around it we cannot isolate this email class we cannot use it independently we cannot test it we cannot provide it the demo database the mock database the in-memory database we are pretty limited to this email depending on exactly this database instance and exec that email driver that we need let's say that we need to uh send an email reminder every monday morning for example so we will just go and create one index file that will live beside our main index and that will be mailer chron file and here in this mailer chrome file we are basically going to require once the email and also the database connection but now this chrome should send emails using a different transfer as we talked about so let's say that here we have the private email transfer service here we would need to initialize transfer service equals to new transfer service uh let's call this one google and then we need to set this transfer service to the appropriate configuration and then we are going to use this email transfer service to send the email now all is great because we're using google transfer service here but here inside our mailer chrome file we don't want to use google we want to use mail gun because google is either expensive or doesn't work or cannot support what we need so we want to tell email to use something else of course we can use the e-files here and then store here the transfer service the config and the username and then the password and the smtp and and i hope that you see how this quickly becomes a mess and becomes very difficult to fix luckily we can use as the module name suggests we can inject the dependencies we want to tell this class what services it should use what objects should it use to perform some tasks that are not related to its own thing that is not the responsibility of email for example to connect to the email service or to connect to the database or something email should focus on its own thing rather than creating other classes and its dependencies that way we can reuse this service or this object in multiple places without worrying about whether the class can make its own dependencies or not we want to provide it what it needs what it should use so let's see the theory behind the dependence injection so without dependency injection we have a situation where we have the controller here which then asks contact for example to get to do some query or the email in the in our example but the main class makes its own dependencies for example the database dependency and everything that it needs on the side and then it does its thing with that database in this case makes the instance and queries the database do something with with the external service and that is great in this case however the more models we have and the more dependencies and the more services we have suddenly it's almost impossible to know which class depends on which service and who needs to create which service with uh what kind of parameters and then we are in a big mess maintaining this and keeping the application clean and simple and easy to use that is why we can use the dependency injection to basically have one place where we will handle all of our dependencies all of our service classes we can use uh we can do it either in controller or we can even use the dependency injection service which a lot of modern frameworks are using which sort of relieves the controller of that responsibility but i will keep it simple here and we will just see how to do it from the controller itself and this way we have a dependency service which takes care of dealing with all the dependency that the classes needs and then it just provides this dependency to all the classes that might need it so that the class can focus only on doing their own thing and they can just pretend that they don't care about which logger service are using or which database or which shipping or which email service are they using they just need to focus on their own thing which is basically executing some of the functionality or executing some of the methods that the service provides this way we avoid the dependency basically that we had in a previous case the contact over here does not depend on this specific database it can work with whichever database we provided even with a fake dummy database that we can use in testing or with the in-memory database or something else the contact class should worry only about its own thing that way we are also enforcing the single responsibility principle and everybody knows what they need to know and how to do what they need to do and you might be thinking that you are never going to change the database or never going to change the shipping provider or email provider but believe me you want all of your applications to succeed you want to shoot for the sky you want to make the best thing out there so that when it comes to reusability you can maintain your code and you can improve and that is the best way also to progress as a programmer there is no way around it you have to make a better reusable code to improve your career to improve the speed the quality of your work and that is something we should think about each time we open the editor and work on some file we always have to be to make it a bit better than we first encounter it so let's implement this one in practice so let's continue with our email cron function here so how do you think we can solve this problem pause this video right now and think about the solution how can we change this email class so that it works with whichever database and whichever email provider is needed and that it's not tied to one specific file or one specific include and module okay the easiest way to is to perhaps make a new database connection file with the exact same functionality so that this email can include this database connection and this google transfer service and all the services that it needs and do the efls around here as we discussed and it might work in this simple example but we want to be prepared for a bit more complex application we hope that this project will grow and then we don't want to dig inside all the files and all parents and all constructors to see if something somewhere is included and we need to change it so let's remove these dependencies from inside the email class and the easiest way is to basically remove them and initialize them before we actually call the email service itself and we can just provide these emails these services to the email object so when we initialize the mailer email we basically here need to make this database connection before and just provide it to the email and we'll do the same with the email transfer service and then inside of our email we are going to accept them so database connection and the email transfer service and then we are going to set this database connection equals to database connection right and the email transfer service equals to whatever we provided and then our application will basically continue using this email transfer service sorry this should be this to send the email however one good thing is as we stocked we don't need the google transfer service here we need the mail gun transfer service which has a completely different password username and completely different configuration which might need some protocol parameter here etc etc etc and our email class should not care about that perhaps there is a different database connection so we can make some remote database connection and provide that to the email class and it will continue working both here but also from here because here we would as well just make a database connect database let's copy this one we can from here provide the different database connection to our email service and we can do the same for the different mail transfer service where we will still use the google transfer service as an example so we can now use our email object our email class with different services with different database and it will continue working no matter how much different databases and different services it gets as long as of course those services have the methods that they need and that is pretty much all there is to dependency injection so it's just a different way of thinking when you need to have some class depending on some other classes uh one thing i should mention here is that here we are making the hard dependency which means that this email cannot even be initialized without the database and the mail transfer service because it doesn't make sense it cannot do anything without that sometimes however you might need a bit softer dependency where we might have to do the mailer something similar with an additional method that will provide for example logging service and here we might provide some new logger external service or some configuration but uh since this is not crucial for this object to work that's why it's called the soft dependency this could be used in different scenarios i will show you in the case study in the next lesson some examples of how and when this is used as a soft and hard dependency and how it fits together what it's what is its purpose they are often used in libraries because they should be very flexible so you cannot predict each and every dependency when you're initializing the library itself so a dependency injection in practice is uh just a way of providing or injecting the dependency to your objects so that the objects are clean and they have their own functionality and they should not care about uh depending of other classes you might argue that we have just moved the dependencies uh outside of the objects inside the controllers they are still somewhere initialized and configured right but we can use the the dedicated dependency injection service for example like a lot of popular frameworks do i will show you in the next lesson and that way we don't have to use the controllers to make our dependencies we can just configure how some services should properly injected and then we would have an even easier way of working with dependencies so let's see how some of the popular frameworks have solved this problem of uh having dependency in controllers by using the dependency service container now this pattern is used as mentioned usually in a bit bigger projects in a bit of bigger frameworks but for example here in joomla we actually have this joomla factory class that does pretty much what we talked about it is giving us the access to uh pretty much the most important parts of the joomla it contains multiple configurations on the different objects so it can give you the database connection for example and it can give you the current user that you are working on and it can give you the date the mailer the configuration the session and pretty much uh all the usual things that you would expect from framework or from a cms and that way we can just use this get user and receive the joomla user without us having to check the session check the id see if the user is logged in logged out whatever we can just say given the user and the factory will create the object for you it will configure it all it will figure out if you have the privileges or not whatever it needs to do and it will give you the user so you can use it in your code that way it's much easier to work with a bit complex objects the laravel has the mentioned service container and the way we use it is we talked about it in the dependency injection container the service container we would just write it what we need uh for example here the type of request and it will generate the request it will populate it for us it will get all the post and get parameters it will put that inside the request and it will provide us this request type object to work with the same goes with the current user the email the uh in this case podcast parser or some very different methods some very different objects that we might use in our application for example we can ask for the event pusher class and uh we can do really a lot of things like get the photo the photo control the file system and whatnot and we can here even bind the services one to each other so that the laravel service container knows how to build the service for us we can just say that when we need the user controller and it needs the variable name we will just pass this variable name the laravel is very very user friendly or developer friendly so it's very easy to configure this uh type of binding and this type of factory services so that we know that we are always getting the correct object when we need it in our controllers or in our models for example here they have the automatic injection or we can do the manual injection doesn't matter but we can just ask for the user repository and we can just say that we need the user repository in this variable users and it will be returned for us the laravel does it automatically but there is a factory service behind the scenes that is actually making this user's repository and giving it back to us so it's using the factories quite a lot drupal for example also uses it on many places for example uh the same example when we are fetching the current user for example when we ask for the current user the drupal will actually get the container get the current user it will get all that we needs it will figure out who the current user is and it will return it to us so that way we just don't have to think about we just ask for the current user and the current user will be returned to us and let's look at one more example the magento for example it even has the dedicated service named factories that will create some object for you magento has quite a heavy and complex logic surrounding all of its objects and basically the only way to access majority of its objects is through some sort of factory so we can ask that service class that will that will instantiate the non-injectable classes so the models that represent a database entry so that way we can isolate the business logic and business code from uh the magento's main the object manager as they call it because as it says here the magento prohibits depending on and directly using the object manager in our code so we need to make those factories to get the object manager to basically get the specific models from the magento by using some sort of factories we will tell it how we want it uh to be configured and the magento will do that for us and that way we can do quite a lot in magento with the custom code so as you can see there is quite a lot of use for factories so it's a quite good concept to be familiar with even if you don't write the factory you will certainly use them if you use some of the popular frameworks so that's a very good thing to know one way to improve your portfolio is to work on some open source project so let me introduce to my small project that has some comment section similar to a forum or a blog post with comments now i've put everything inside one index.php file here so that we can see what's going on rather than hunt through the controllers so that way we can focus on it for the easier homework right we get some data from the form that the users would submit we would then update the post in this case we are the administrator so we get this admin user and here we as administrator are changing this comment and uh just formatting some style it doesn't matter we are updating the post so we need to get the admin user actually the current user that's us who are logged in and we need to figure out and configure that user so that it has all the correct groups and we need to find it from the database using some active record in this case we then need to update that post and we need to put the reason for the update that this username the admin has changed the styling for example and then we need to get the user who has commented on it and to send him an email to notify the author that his post has been changed now as you can see the problem here is that each time we need the user we need to configure it we need to find it we need to get the correct user we need to get the corres user group in this case these groups are just predefined here in this file but it can come from a different configuration etc etc so it would make sense to move this user retrieving somehow somewhere that it's easier to work with now how can we do that well we just extract it into a single factory right since this is relatively easy pattern to follow we just extract this part out right but there are multiples ways of going forward here actually for example are we going to have two methods in factory one for admin and one for regular user or one special method for the current user here when we are getting uh the user from the session also are we going to let the factory decide what type of user is going to return or to create will there be multiple types of users because we have right now only single type the user right are we going to have an option of specifically asking for a user group you see that even though this pattern is easy to understand the implementation can take a bit of thinking and planning because there are multiple ways forward that's why we have this homework that's why it's very important you just sit down and think maybe you can just write it on paper what are your thoughts about it and see what confuses you and that way you can figure it out that's why we practice so that we can be comfortable with those situations so think about what you would do in this situation download the source code it's a few files and try to run this homework as you can see it's only a few files so it should run pretty easy and try to implement one or maybe even more ways of fetching the users and i will do the same in the next lesson now please use the comment section for this lesson if you have any concerns or if you would like to discuss your solution
Info
Channel: Applicable Programming
Views: 7,430
Rating: undefined out of 5
Keywords: programming, web development, php oop project, php design patterns interview questions, php design patterns interview questions and answers, php design patterns, php design patterns tutorial, php interview questions and answers, php dependency injection, php dependency injection tutorial, php factory pattern, applicable programming, design patterns php, advanced php, php advanced
Id: a7bgGhSTTb0
Channel Id: undefined
Length: 31min 34sec (1894 seconds)
Published: Wed Apr 14 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.