Learn SOLID Principles with CLEAN CODE Examples

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so we have a circle we have square so here i'm going to teach you about maths yes i want to teach you about maths what do you know about maths tell me the truth ah cool i know it's trigonometry algebra econometry geography okay what else and everything to earn with tree you don't know the thing what's going on guys assalamu alaikum welcome to amigos code in this video i want to teach you everything you need to know about the solid principles yes so lead principles s o l i d this is a video that you've been requesting for some time and there you have it solid is simply an acronym for the first five object oriented design principles by robert c martin or simply uncle bob if you read the clean code book which is by far one of the best books that i do advise you to read and you can find a link in the description of this video but basically solid helps us to write better code help us to write code that doesn't suffer from code smells if you were to jump on a large code base that doesn't use solid principles then i can tell you that you will be suffering as an engineer whether it is to add new features refactor fixing a bug it will be really difficult whereas if you implement solid then you can guarantee that you are following the best practices for building applications whether it's small or large scale so if you new to my channel literally take one second subscribe also smash that like button so i can keep on recording videos like this and comment down below as well so let me know what other videos that you want to see next design patterns maybe literally anything and also on discord community i have a channel which is dedicated for video ideas so you can pop all of your ideas in there and i try to make my best to record videos for you that will help you to become a better software engineer and also we have a private facebook group which you can join and uh yeah so the amigas amiga community is awesome and you should be part of it without further ado let's kick off this video and if you've missed out nordvpn still has their 72 percent of their two-year plan which i highly advise you to take advantage of so myself i use node vpn actually i bought node vpn before they reach out to me and i definitely recommend if you want to browse on the internet privately i do use node vpn as a software engineer and you should also do it link will be in the description of this video now let's go ahead and learn about solid principles okie dokie so in here i'm within intellij and i've got the solid principles already written for you so solid is just the acronym for single responsibility open close list of substitution interface segregation and dependency inversion so i'm going to cover everything that you see here now i already went ahead and created a few classes just to speed up things but basically what we have in here is a main method with couple of instances in here so we have a circle we have square and we also have the area calculator so here i'm going to teach you about maths yes i'm going to teach you about maths what do you know about maths tell me the truth all right cool i know it's trigonometry algebra econometry geography okay what else and everything to end with tree you don't know the thing mashallah mashallah right cool so with your awesome skills about maths let me teach you about shapes and solid principles so in here let's just look at this method in here called area calculator so this method in here pretty much just returns a sum of all the areas for the different shapes that we have so currently so we have a circle class and we also have a square and then this pretty much just receives a list of shapes and then if it's a square it calculates the area of a square which is math.pow the length and then you pass two in here and then if it's a circle is the pi right here times the math.pow and then radius so instead of length is the radius and then you pass two inside of this function in here so you can see that the circle and the square there are really simple classes in here so length for square and radius for circle and if i run this main method in here we should have a sum of 414 so nice and easy now let's begin by learning the single responsibility so each class should have only one sole purpose and not be filled with excessive functionality what does it mean so if i go to this area calculator in here and let's say that we want to add a method to print the result so the result of this sum in here as a json object well we could do this so we could open up the area calculator and within it we could say for example public and then string and then json and then inside here we could just say return for example and this will be a string just like that and this will be some column and then percent s percent s dot formatted and then we could say sum and then pass the shapes in here and if i extract this to parameter just like that and there we go and this and now we have this method that gives us the json version for the sum of all the shapes now if i go back to main and instead of saying sum equals to sum i could just say in here so i could just basically get rid of all of this and then say area calculator dot and then json and then pass the shapes so nice and easy if i run this you can see that we have some colon and then four one four now we just broke the rule of single responsibility why let's have a look so within area calculator we said that single responsibility a class should have one single purpose and in here we said area calculator we have one method that does some for the areas but this method here is basically just printing the json blob so what we should do is so this actually should be on its own class so here again so each class should have only one cell purpose and not be filled with excessive functionality so let's say that instead of json we want a csv right so this will be a csv so csv and the csv version is relatively straightforward it's just like this so sum and then comma and then the actual value if i go to main in here and duplicate this and if i say csv instead and then run this you can see that this is the json formatted version and this is dcsv but we are breaking the rule so error calculator is now filled with excessive functionality so this or these two methods they don't belong here so what we do is we take this so let's just cut from here and let's create a new class and i'm just going to call it for now shapes and then printer for example so there we go and basically we're going to paste that in and now here we could just say for example int and then sum and we could actually pass the sum or actually the instance of error calculator but for now let's just say sum in here and i'm going to say shapes and then sum there we go and this will be shape sum as well so underscore sum and we take in sum from here we pass it in here and then we pass some in here there we go and now if i go to uh the main method so in here this now throws an error and that's because we need the shape sprinter so let's just have shapes printer and i'm going to call it printer equals to new and then shape sprinter and then instead of saying area calculator we could just basically take the printer so i could just say printer there we go and this now will take the sum so let's just pass some in here the same with the line above so this will be now instead of json this will be csv and if i run this now you can see that this works the exact same way but now we have a dedicated class which deals with formatting the sum of the area for each shape so this is single responsibility so this class has one responsibility and that is to format to json csv and maybe if you want html so on and so forth so this is basically single responsibility in action open closed let's learn about this one so this one is quite interesting so classes should be open for extension closed for modification so let's say that now in here we have a new shape we have a new shape let's say that we have the shape so let's just have a new shape in here and this will be a cube so let's say that we have a cube and for now let's just leave it empty and if i go to area calculator now have a look so i've got a list of shapes in here or a list of a list of objects and i've named shapes now we have a cube so if we want to calculate the area for the cube we need a new if statement and here i'm going to say that this is a cube just like that and whatever logic that we need for the cube itself but here we just broken this rule in here open closed so classes should be open for extension and closed for modification so what we're doing here we are modifying this class so each time that we have a new shape we are adding a new if statement so if i have 10 extra shapes so let's say cone rectangle so on and so forth we'll have a bunch of different if statements so this is bad practice so how do we fix this so what we do is we actually create a new interface and here i'm going to say shape and this right here so let's just deal with this so this shape will have one single method or this interface will have one single method i'm going to say we can say double and then area and there we go so this is the area now for circle we basically say implements and then shape so this is a shape and we need to implement the abstract method there we go and if i go to area calculator in here let's just take this right here so that's a square so whoops that's the area there and the return type will be basically that exact same thing and here i don't need to cast this anymore i could just say get radius and job done so the same for square so here implements and then shape let's implement the method and again a recalculator let's grab this and then return this exact same thing again no need for casting in there and job done so the same for cube in here so we could say implements and then shape right oops so shape there we go and i'm just going to leave this empty for now but now if i go back to area calculator so area calculator have a look so you can see that this class in here it's open for modification but we don't want this so what we do is we get rid of all of this so can get rid of that and now i can say so here this instead of an object we'll take a shape this will be shapes and this will be shape and we can say sum plus equal to the shape dot and then area have a look and i can actually inline this like that and you can see that now this class is so simplified right now so if i go back to i think it's main which is complaining now yes so here this will be shape and there we go so if i run this we should get the exact same output have a look 414 and we have the json version as well as the csv version so this means that now if i so here if i say let's add our new so i think was cube that we had so cube equals to new cube in here and if i basically pass cube now and if i run this this will give me the exact same result that's because cube right here we just said 0 but let's just say that we have 100 so run this this will give us 514 right and you can see that so if i have for example uh let's just say a rectangle so reg tangle class and oops mistake there can't spell rectangle so wreck tangle rectangle just like that and let's say that this is 20 right so now you can see that if i go back here so open close so class should be open for extension and close for modification so now we are extending the area calculator by adding a new shape but we're not modifying it that's the beauty of using interfaces in here right so in other words you should not have to rewrite an existing class for implementing new features that's what we've just done so if i go back to main in here and let's add our rectangle rectangle equals to new rectangle and here i can pass a rectangle so i can pass rectangle just like that and you can see that things still work so if i run this bingo so five three four so that was basically open close principle moving on to lisk of substitution so lisk of is one which people get confused and whatnot but let me just oversimplify this so this means that every subclass or derived class should be substitutable substitutable substitutable for for their base or parent class so what this means so let's say that we have in here a class and i'm going to call this as no and then shape there we go so if i press enter and here if i say implements and then shape right here and let's implement the area and let's say that here i say throw new illegal state exception cannot call to late and then area so in this instance right here so where we have a shape so we said no shape implements a shape so no shape implements shape and we are overriding the area method but this class no shape cannot cannot calculate the area so here we broke the rule let me show you so if i go back to main so if i go back to main and let's just have the shape in here so no shape equals to new no shape and let's just pass the no shape here then if i run this oh have a look cannot calculate area but we we said that this so this no shape is a shape so that's what we said right so shape no shape equals to no shape run it boom you can see that we are violating the principle here because now the derived class is not substitutable for their base or parent class so liskov says that so if i go back to no shape so if you implement so this is the parent so here we know even using extending uh the extending keyword so this here is the superclass so here we're saying that no shape is a shape but it cannot calculate the area nor basically it cannot obey to the contract of this interface so therefore we broke the rule so similarly if this shape right here had a bunch of other methods that we had to implement and let's say that no shape could implement some and does know how to implement others so therefore it will never be substitutable by so here by their base or parent so every subclass or derived class should be substitutable for their base or parent class so this is lisk of inaction so if i go back in here and let me just basically get rid of this so i want this code to run and next let's move to interface segregation so interfaces should not force classes to implement what they can't do large interfaces should be divided into small ones so what this means is so here we have a class called cube so cube is a 3d shape so here we can actually calculate the volume now you see we have area and we could say volume right so if i go to shape and then here if i say double and then volume in here and if i now open up circle we broke the rule right because with a circle circle is not a 3d shape or three dimensional shape but here what we are telling it to do is to implement so implement something that it can't do right so we could just return zero for example and then the same with um the where is it where is it where is it rectangle we could say basically implement this and the rectangle as well it doesn't know how to calculate the volume in here so what we do in this case in here so have a look interfaces should not force classes to implement what they can do so instead what we do is let me just go back in here and the same for circle so let's just go back and then if i open up the shape class so this has to come out from here and instead i can just create a new class and i can say three dimensional and then shape this will be an interface oh i can't type today dimensional and then paste the volume method in here now cube so this is a shape right but also it's a 3d shape so implements we call it three-dimensional shape and then here i can implement the method and boom so now we are leaving circle untouched because it doesn't know how to calculate the um the volume but the same thing for rectangle and i think we had square so this is how we basically tackle interface segregation so interfaces should not force classes to implement what they can do large interfaces should be divided into small ones that's what we've just done moving on to the last principle which is dependency inversion so what this says is components should depend on abstractions and not concretions i.e we should really be implementing two interfaces so let's open up the i think it was uh i think it was yeah shapesprinter in here so shapes printer so here we have shapesprinter and before this was a list of shapes in here so let's say that we want to bring the area calculator so private and then area calculator and then we could say equals to new and then area calculator now we could then basically pass the shapes so here we could say a list of and then shape and then shapes and we could say so here area calculator dot sum and we can pass shapes inside right so we could do the same for csv in here and this now has to be the exact same thing so just like that there we go and basically here we are actually breaking the rule so here we have two problems so one is if we make a change to a recalculator so let's say that we make a change in here then we actually are breaking the open close principle but also here we are depending on the actual concrete class and not the abstraction so how do we solve this well it's simple so here what we could do is we could go to area calculator so what i could do is i could refactor this and basically have this implement an interface so here if i basically select this class and then go to refactor and then extract or introduce and here we have interface so here members from the interface i want to select this one here and i'm going to say area so usually people say i area calculator and i'll just leave it i so that you understand that this is an interface for now and this will basically extract the methods to an interface the same one so i'm going to refactor this there we go and basically what's happening now is have a look so area calculator implements now the eye area calculator so this is something very common that you'll see people do and we have now our interface which is sum in here which contains the method sum but now inside of the shapes printer so what we could do is we can basically say private final and then i and then area calculator just like that and then pass that into the constructor so i'm going to refactor this for a second and now instead of depending on the concrete we basically are depending on the abstraction which is this interface and here we are using dependency injection so let's go back to main so that we can run this so main and here we need to change couple things so here we could actually say that this is the i and then area calculator and this is one implementation but also so let me just put this on this line so you can see properly but also in here we have two problems so printer and then dot json and then we pass the sum so this instead now will receive so have a look so if i press command p shapes so if i say shapes there we go there we go and if i run this you can see that we have the exact same output and to be honest this was so here dependency inversion components should depend on abstractions not on concretions so you see that i do this quite often on my videos where for example i think i've done a video with the twilio where instead of saying twilio and then have that class have all this all the methods so what i do usually is i extract the send method to an interface so let's say sms sender for example and then you'd have a class called twilio sms sender that implements the sms sender and that means that if you want to make a change right so let's say that the so in this case let's say that we have a different area calculator in here right so if we have a different area calculator that basically subtracts we can just basically copy that so i'm going to say area calculator v2 let's just say that it's a version 2. so here if i go back to main so let's just go back to main for a second there we go and now i can have a new version so here i could say i recalculated v2 let me put this full screen so v2 and area calculator v2 now check this out i can just replace this in here inside of the shape sprinter and nothing breaks nothing breaks so you can see that we didn't have to change anything around we didn't have to mess with this class in here shape shapes printer so we didn't touch anything all we did was we added a new class we implemented the interface and then we swapped the implementation right open close in action there as well so this is pretty much solid principles with shapes hopefully this was super easy and fun for you to learn and hopefully now you can start to write code which um doesn't smell all my days hahaha code that you can easily refactor and um yeah so coda uses the best practices if you enjoyed this video give me a thumbs up and also comment down below this is all for now i'll catch you on the next one you
Info
Channel: Amigoscode
Views: 117,336
Rating: undefined out of 5
Keywords: amigoscode, solid principles, solid principles java interview questions, solid principles with examples, java, clean code, clean code uncle bob, clean code java, clean code examples, code refactoring, code smells refactoring, code smells
Id: _jDNAf3CzeY
Channel Id: undefined
Length: 28min 35sec (1715 seconds)
Published: Thu Apr 21 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.