#2: Open-Closed Principle (OCP) in PHP, Laravel | SOLID Design Principles

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Music] hello everyone welcome to our channel my name is harish kumar today's topic is open closed principle in solid design principles the main idea of this principle is to avoid breaking changes when you add new features to the existing code the definition of this principle is little confusing it says that the software entity you may think of it as a class or method should be open for extension but closed for modification sound confusing right i was also very confused when i first hear this let me try to simplify this the open for extension part means we should design our classes so that new functionalities can be added if needed and the clause for modification part means that the class should be only modify in case of a bug fix not for adding new functionality the new functionality should fit in without modifying the original class now the question is how do we do that how you would change the behavior without modifying the original code and that's where we come back to the term extension still confused don't worry let's look through some examples that will make the difference between them the first example i am going to show you is the area calculator that is the very common example for open closed principle you can also see the same example in many article and blog posts so after this i will show you some more examples so here the idea is you have some rectangles let's say rectangle 1 rectangle 2 rectangle 3 and rectangle 4. and your job is to calculate the total area of these rectangles so let's create this so first let's create a new class let's say its name is rectangle.php namespace solid and class is rectangle class and this class has public property width and public dollar height and here we have construct and it is going to accept width and height next here i'll say dollar base width is equal to dollar width and dollar this height is equal to dollar height our next job is to calculate total area of given rectangles here i'll follow single responsibility principle so i will create a separate class area calculator to calculate total area of all given rectangles so let's create a area calculator class class area calculator next here i'll add method total area and it is going to accept array of rectangles now to calculate the total area here i'll say dollar area is equal to initially it is zero and here i'll add for each loop dollar rectangles as rectangle and then here i'll say dollar area plus equal to dollar rectangle width multiply dollar rectangle height and next return dollar area now our area calculator is ready so let's test this so in the web.php let's remove all of this and here i'll say return new area calculator and then total area and in this method we are going to pass array of rectangles so let's say new rectangle and this rectangle going to accept width and height so let's say 10 20 now let's go to browser and see localhost 48 000 great let's add another rectangle maybe let's say it's width is 20 and height is also 20 so refresh great it is working fine now let's say after some time we have also requirement to get the total area of circle as well so no problem let's implement this add a new class circle dot php and now let's copy all of this code from the rectangle class and paste this in the circle now here class name is circle and here instead of height width we need radius and the constructor going to accept radius and here i'll say this radius is equal to dollar radius and let's remove this now in the web dot right here if i pass new circle and let's pass radius 10 now it is not going to work because in the area calculator we need to modify this method because right now it is calculating the total area of rectangle because here we need to modify the original code so clearly it is violating open closed principle because here we need modification to add new feature for example first thing instead of rectangles we should call shapes and and here it is going to be shape next this formula is for calculating area of rectangle and formula for calculating circle area is different so to fix this here we can add if condition if dollar shape is instance of rectangle then use this formula else here i'll say area plus equal to dollar shape radius multiply shape radius and multiply pi now here it should work let's see refresh and here we go it is working now what if you have also requirement to calculate total area of triangle now you may say that don't worry add another if condition and check if the shape is triangle similar like this now in these cases do you really think we should do something like this again do we need to update the code every single time we make a change this is sort of thing that increase the line of code in the method and later it becomes very difficult to understand what this method is doing or at least it is sort of thing that introduce breakage the open close principle says that the class should be closed for modification but you can see this is not closed because every time we need a new shape here we need a modification in this logic so instead of adding area formula right here we will create a area method in the shapes and that will return its area so let's go to rectangle and here i'll create a method area and it will return this formula and here it will be dollar this next in the circle here also we will add method area and it should return this formula and instead of shape it should be dollar base great now right here in the area calculator we can remove this and here we can say dollar area plus equal to dollar shape area this method and now if we go to browser it should give the same result but it is not done yet the open close principle suggests that we should separate the extensible behavior behind an interface now you may say that this code is working fine why we need interface let me explain this now let's say after some time you have requirement to add area of triangle as well so let's create this class triangle dot php name space f solid and class triangle and this class has public triangle base and public triangle height now let's add construct and it is going to accept base and height the next dollar this base is equal to dollar base and dollar this height is equal to dollar height now if we see in the rectangle to calculate area we have created a area method now let's suppose a new developer is creating this triangle shape and he do not know that the shape class should have area method so let's say instead of this area method he created a new method let's say its name is get area and it is going to return dollar this base multiply dollar this height and divide this by 2. so now in the web.php if i add new triangle and let's pass base is 20 and height is 30 and it should not work because in the area calculator here we have called method area but this triangle shape does not have area method instead it has get area so it will throw an exception let's see refresh and here we get call to undefined method triangle area and that kind of problem is solved by the interfaces so let's create an interface so here i'll create a new file let's say its name is shape interface dot php namespace is app solid and interface shape interface and it should have method public function area now here in the area calculator here i'll say if dollar shape is instance of shape interface then we should add the area otherwise else it should throw new exception let's get the class name of the shape so here say get class and pass dollar shape and then say should implement app solid shape interface so here what we did if shape is instance of shape interface then add the shape area otherwise through exception that the class should implement the shape interface now let's go to browser and refresh of course we will get error that rectangle should implement shape interface so let's go to rectangle class and here implements shape interface this shape interface ensure that this class has area method that is defined right here in this interface so if we go to browser and refresh again the error will change it will say the circle class should implement the shape interface and let's go to circle class and implement shape interface and let's go back to browser refresh and again we will see same error for triangle class as well and in the triangle class implements shape interface and my editor immediately giving me error that the triangle class should implement method area so let's rename this method area and let's go to browser refresh and it is working now now look at this area calculator class we never going to need any modification right here so this area calculator class is closed for modification and it is open for extension in future if we need to add any new shape we will just create a new shape class and implement this shape interface and this shape ensures that new shape has a area method that we have called right here i almost forgot to talk about this condition here i checked if shape is instance of shape interface and then call this area method so when you see in your code you are checking the type of object it is a signal that you might be breaking open closed principle i added this condition because i don't know how to type hint that these shapes contain array of shape interface object so if i don't add this condition let's comment this in that case any class which does not implement shape interface is acceptable in this method for example let's say this triangle does not implement shape interface in that case it is acceptable and if we go to browser refresh we did not see any error so by adding this condition i ensured that these shapes contain instance of shape interface because here i am checking the type of interface is so in my opinion that condition is okay there is one way i can type in that this shape is instance of shape interface that we can do by using php spread operator so here instead of array here we can say shape interface and three dots shapes now let's dump these shapes to see if it is array of the shape interface now let's go to browser refresh and here we get error the total area method must type of shape interface array given yes of course in the web.php right here now it is not going to accept array so instead what we can do here we will say dollar shapes is equal to this array array of shapes and now we can pass these shapes right here using spread operator like this now it is valid now go to browser refresh and you can see it is an array of shapes instead of this we can also pass these shapes without array like this and now we can remove this shapes variable now go to browser refresh and we get exactly same so now in the area calculator let's remove this dump and now we can remove this if condition and it should work and it's working now you can see this code looks more clean now let's say in the triangle class if i remove this implement shape interface and let's go browser refresh and here we can get error argument type must be shape interface and triangle given so now let's undo this refresh and it works i hope this was easy to understand now let's see one more example let's say we have a payment service class so payment service dot php namespace solid class payment service and this class has a method let's say pay let's say it is going to pay the payment via paypal now later your application may accept stripe payment method as well so here what you will do this method going to accept payment method variable and next here i will check if payment method is equal to stripe then call dollar this payment via stripe and then we will create this method and if payment method is paypal then call method payment via paypal and again create method payment via paypal now pause the video and think yourself is this class is closed for modification and the answer is no because in future if you need to add one more payment method then you're going to come back to this class and going to add another if condition and create a new method so when you return these cases and modify them you introduce the possibility of breakage or more bulk however if we instead use interfaces to extend functionality when we need to we never have to worry about any of this stuff so here we should extend this functionality behind the payment method interface so let's create this payment method interface dot php namespace app solid and interface payment method interface and it should have public function let's say make payment now we will create a dedicated stripe payment method class and paypal payment method class so let's say new file stripe payment method dot php namespace app solid and class stripe member method and it should implement payment method interface and this payment method interface ensures this class has make payment method and let's say it returns stripe payment next let's create a paypal payment method namespace app solid and class paypal method and it should implement payment method interface so next let's create make payment and it returns paypal payment and now in the payment service right here we can remove this and here we will type in it is going to accept payment method interface dollar payment method and this interface ensures the payment method has make payment so here we can call return payment method make payment so how we can use this let's go to web.php and let's comment this and here we can say return new payment service and we will call pay method and it is going to accept new stripe payment method and let's go to browser refresh and here is the stripe payment if we need we can pass paypal payment method refresh and here we have paypal payment now you can see this payment service is closed for modification if we need to add another payment method we can just create a new payment method class and extend payment method interface and this ensures that that class has make payment method and we don't have to touch existing code for example let's add a new payment method cash on delivery so here i'll add a new class let's say its name is cod payment method dot php class codpm method and implement payment method interface next create method make payment and it returns cash on delivery now if we need to switch payment method we write here we can say cod payment method like this and it should work and here we go it's working we have added a new payment method without touching existing code let's see one more example so so let's close this in the previous lesson of single responsibility principle we have seen an example of sale reports so what here our job is let's go to web.php let's comment this here so what here we want we want new sale reports and here we want to fetch sale reports between start date let's say 1st jan 2022 and end date is 31st jan 2022 and then export in let's say csv format now here in this example you can see we are using method chain after calling this between method we called export method but if we see sales report class this between method returns a query so if we go to browser and check this we should get error right here let's see refresh and of course we will get error method expo does not exist because in the current implementation we cannot change export after between method so to allow this chain in the sale reports class here we should return dollar this instead of this query so here what we will do here i'll say public sales and then right here we will say dollar these sales is equal to this query now here we return dollar this so it should be valid now let's go to browser refresh and we get nothing because here because here we did not return anything and this export method is doing nothing let's say this export method except format and let's return this format refresh and here we get csv now here this export can accept different formats for example let's say format is pdf then it will return pdf format and add another if condition if format is csv then return csv format and later we need a new format then we are going to add another if condition and so on and these kind of things introduce code breakage and it is violating single responsibility principle as well as open close principle because this method should be responsible for only one single responsibility and you can see it is also not closed whenever we need to add new format we are coming back to this method and add a new if condition so let's extend its behavior behind interface so here i'll create a new interface and let's say its name is sale report format interface dot php interface sale report format interface and it should have public function let's say export and it should accept sales data so now let's create a pdf export format so pdf x4.php class is pdf export and it should implement sale report format interface and it ensures that this class has export method so method export and it is going to accept sales data and next return pdf export and now in the cl reports class right here we can remove this and instead this export method going to accept sale report format interface and let's say variable name is format and now we can confidently return format export and we can pass dollar this sales this one and now in the web.php right here we can we can pass the format which we want to export that is new pdf export now let's go to browser refresh and here we get pdf export similarly if we need to add a new format we don't have to touch this original class we will just add a new class let's say csv export and copy all of these here we need to say class name is csv export and return csv export that's all we need and right here when we are going to export here we just need to pass csv export class and it is going to work we have now touched the original class and added new functionality the open close principle strongly promotes the use of interfaces to enable you to adapt the functionality of your application without changing the existing code this is what we refer to as polyformism the ability to have different behavior while sharing the common interface now in these examples you may have also noticed that how these design principles sort of have each other's back you will find lots of similarity between them now here you may see that i have created all these classes in one place in the solid directory but you should organize these classes according to the feature this is all in this video thanks for watching if you like the video hit the like button share this video and don't forget to subscribe us see you in the next lesson [Music] you
Info
Channel: QiroLab
Views: 6,952
Rating: undefined out of 5
Keywords: Open-closed Principle, Open-closed principle for classes, Open-closed principle for interface, why use Open-closed principle, why Open-closed principle is important, Open-closed principle with example, solid php, solid laravel, solid design principles examples, solid design principles in software engineering, solid design principles interview questions, php interview questions, laravel interview questions, learn with qirolab, qirolab
Id: AOTb2zIpdcQ
Channel Id: undefined
Length: 32min 52sec (1972 seconds)
Published: Mon Apr 04 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.