Learn SOLID Principles Easy in Python

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everybody and welcome back to another video in this video we're going to go over a fundamental computer science and software engineering concept known as the solid principle which stands for single responsibility open and closed principle the liskoff substitution principle the interface segregation principle and the dependency inversion principle so solid s-o-l-i-d has each one of these principles embedded in the root of computer science and software engineering solid allows you to be able to create maintainable and reliable scalable software and this principle was created by Uncle Bob who is a leader in creating all of this software Journey that we all are a part of so if you want to write more maintainable flexible and just overall robust code you're going to want to follow the solid principle so let's dive into each one the single responsibility principle means every class or object or method in the entire application should only only have one responsibility every single thing in your code should be completely organized to the fact that there is only one responsibility for each specific piece of code in your application the second principle which is known as the open close principle should allow us to be able to add functionality into our code without adjusting or changing current existing code the list off pattern should allow us to be able to use interfaces as a is a relationship but we should only have to use the interfaces that we need to be able to create or perform a specific action in our application The List golf principle will increase flexibility and performance and allows for our application to really be able to scale following this principle the interface segregation principle means that we shouldn't be dependent on other interfaces or other areas of our application it helps reduce coupling of our application to make our application completely module and and decoupled from other pieces of the application now lastly the dependency inversion principle allows us to add abstraction to our application which just means our high level modules should not have impact on our low level modules unless we specifically ask it to now all of this combined allows us to be able to create really modular and scalable code so let's dive in and let's look at code examples of all five pieces of the solid principle so if we look at the project that we're going to be using for this video we can see that we have solid already created we have the single responsibility principle we have the open enclosed principle we have the liskoff substitution principle the interface segregation principle and the dependency inversion principle so all five and we can see that it spells solid s-o-l-i-d now the very first one that we're going to be going over is the single responsibility principle and the single responsibility principle is kinda how it sounds the single responsibility means each class or function only should have one responsibility and that helps reduce bugs while increasing performance of the application because we know as a developer and the program knows that each item within the application only has one responsibility so if we open up our SRP file which stands for single responsibility principle we can see that we have a new class item and this item takes in a function where we are just going to initialize itself so we're passing in self name and price and then we say self.name equals name and self dot price equals price so an item has a name and a price the next class that we have is order and order will initialize itself with a order ID and item so it's a list of our object items and it can calculate the total price for a specific order so there's a calculate total where it passes in itself and then it adds the sum of all the item prices and then we return the total class order manager has one function place order self and Order where again we get the total from the order.calculate total and then we're just going to print the total and we have a list of items and then order equals order one two three order items and then order manager equals a new order manager and then we're going to place the order of the order so if we look through this we can see the single responsibility principle because each item only has one responsibility the item's responsibility is just to be an item the order's responsibility is to just calculate the total so we're going to create a new class that takes in a list of items and then we're just going to calculate the order and then we have the order manager which is just to place the order as you can see we could have all of these in one entire class but the class then will have a different responsibilities we really wanted to make sure that hey if we are going to create this application we want to use three different classes all with their own functionality that needs initialized so then we can really start isolating all of the responsibilities of the application into different classes and into different functions so we can increase readability and increase performance and decrease bugs for our application so the single responsibility principle is really just to make sure everything only has one responsibility the second principle is the open closed principle so if we take a look at the open close principle we can see that we say from ABC import ABC and then our abstract method and ABC is really just an abstract Base Class that comes from Python and we can use it for a standard way of inheritance so we're going to have our class shape that Imports ABC we're going to annotate it with our abstract method so the application knows that it's an abstract method and then we have a function of Def area where we just pass in itself now the open closed principle states that software entities whether that's classes methods or functions should be open for extension but should be closed for modification so what does that really mean that means you should be able to extend the behavior of a class or a function without modifying the entire application so we have our class shape ABC and we have our class rectangle which takes in a shape we can see that it's going to initialize or instantiate itself with the width and a height and we have an area function inside that Returns the width times the height well that's how you find the area of a rectangle well we also have class shape and shape takes in a radius so self dot radius equals radius and then we can find the area of the radius by saying Pi which is 3.14 times radius and now here is where the open closed functionality really comes into play we have this function calculate total area we'll calculate total area can take in shapes and as we know a circle and a rectangle is a shape and then we can get the total area by just running the sum of shape dot area so this is the function that's inside rectangle and circle and then we can do that for each shape in the list of shapes and then return the total area so here we're going to have a list of shapes which is a rectangle so we're passing in the height and the width which is four and five and then we're going to pass in the radius for us New Circle we can then find the total area by saying calculate total area and then passing in the list of shapes so if we go inside here and we check out the open close principle and we do a python and we run the ocp dot Pi which is the open closed principle file we can see that we get a total area of 48.26 and that's because we are calculating the total area for all shapes that we pass in and it doesn't matter what shape it can be a rectangle or Circle so we are extending the behavior of our calculate total area function but it does not matter what Behavior or what shape we pass in so we are going to be using the open closed principle here so we can keep the application very dry so we don't have to repeat ourselves and we can pass in any shape we want to this function now for the third principle is the liskoff substitution principle and if we take a peek at this file we can see that it's going to be looking fairly similar to our last one now the list off substitution principle means that a subclass should be able to replace the parent or the superclass whenever it is needed so let's take a look at this class rectangle we have our class rectangle which initialize itself with its width and height we can set our width we can set our height and then we can return the area so width times height well we also have a new class of square which takes in rectangle so we can set the width by saying self.width and self.height and then we can set the height well we can see that we have our def print area which is a rectangle where we can say rectangle dot set with the four and rectangle dot set height to 5. here we can say area equals a rectangle dot area and we can print the area and then when we initialize them we can say rectangle equals rectangle 0 0 and rectangle equals Square zero zero so if we jump into this application and here we can see the rectangle has an area of 20 and the square has an area of 25 and that's exactly what the linskoff substitution principle wants to happen in this example we can see that square inherits rectangle in the print area functionality only works with a rectangle but since Square inherits rectangle we can pass a square into the same print area functionality now let's go ahead and look at our interface segregation principle now the interface segregation principle states that a user should not have to use an interface should not depend on using a interface if they do not want to so again we can see that we import ABC and our abstract method we have our class vehicle of ABC where we pass in our abstract method and then we have our start engine and our stop engine which also has an abstract method we have our class car which is a type of vehicle so we're passing in vehicle where we have a start and a stop engine where we just print the car engine stopped in the car engine started and then we have our class boat vehicle which also has a start and a stop engine well if we create a new function of test vehicle and we pass in a vehicle we can do vehicle.start engine and vehicle dot stop engine and we can create two new objects of car and boat and then we can do test vehicle for both so here we can see that the vehicle has a start engine and a stop engine and the car in the boat only implement the interfaces and the functionality that they want without having to do everything and that's really the power of the interface segregation principle is that you can control exactly what you want to import and it's not up to the interface to force you to do anything that you do not want to do for your application so if we go into this application we can see that we get the car engine started the car engine stopped the boat engine started and the boat engine stopped so we are fully in control of what we want to pass into our application and the interface segregation principle allows us to have that much more control over our application all right and now let's jump into the very last principle which is the dependency inversion principle now the dependency inversion principle allows us to change logic without having to replace the entire application so let's say we have this class payment Gateway which is which has a new function of process payment where we pass in a payment and for this example we're just going to say print making a payment on stripe but just for your imagination pretend that there's some business logic that is surrounding the make payment on stripe this could be make payment on PayPal or through a specific bank well we have our class item which will instantiate itself with a name and a price we have order which takes an order ID items and a payment Gateway we have our calculate total which is the sum of all the item prices we have a place order which is a total of the calculate total functionality and then we call our process payment which remember for this example is making a payment on stripe but we can pretend it's anything we want and then we have a high level module so another part of the dependency inversion principle is that a high level module should not rely on a lower level module that a high level module should not rely on a lower level module so we have our class order manager where we pass in a order and then it has its own function of place order so we're going to initialize a new payment Gateway we have our three products which is product one product two and product three all with different prices of 10 20 and 15. we create a new order of order one two three that's the order ID that this order functionality relies on we pass in our order items which are these items right here and then we have our payment Gateway and our payment Gateway again is going to be stripe but we can but we can say it's going to be anything we want and then we have our order manager and then we place our order so if we jump into this function we can see that it's going to be making a payment on stripe so if we scroll to the top it's going to do all this functionality of creating an order manager and then placing an order based on these items but this payment Gateway can be changed to anything we want so right now we have it making a payment on stripe but we hypothetically could change us to making a payment on PayPal or making a payment through a specific bank we don't need to be using stripe so if this was business logic instead of just printing a statement and this was a business logic that connected to a stripe account we could connect this instead of stripe to PayPal or vimo without having to change any other business logic within our payment Gateway therefore all of the rest of the code that instantiates a payment Gateway or uses a payment Gateway does not need to be changed to now work with a different payment provider this payment provider will work fine with whatever we're using because we're just changing the business logic behind scenes but not changing the impact from a higher to a lower module so for example if this was business logic we can literally just come in here and type in vimo so now if we rerun the application it's not going to say making a payment on Vimeo now this is super simple because we're again reaching a print statement but think of the power if we had business logic here and we need to change the business Logic the rest of the application does not need to be impacted now this again is the five principles to make up solid which is the single responsibility principle the open closed principle The List golf substitution principle in the interface segregation principle and lastly dependency inversion principle so if you really want to break into computer science or maybe you're already in computer science you just needed to recap on what the solid principles are here they are I hope you enjoyed the video and I hope you enjoyed the small pieces of code that created the five principles and if you like the video please subscribe and hit the Bell leave a like and comment and I will see you in the next video
Info
Channel: Eric Roby
Views: 3,005
Rating: undefined out of 5
Keywords: solid design principles, single responsibility principle, solid principles, solid principles in python, solid principles made easy, python, python best practices, solid principles interview questions, solid principle, python principles, python design patterns, uncle bob, uncle bob solid principles, Single Responsibility, Open/Closed principle, Liskov Substitution, Interface Segregation, Dependency Inversion, python examples, python advanced topics
Id: ZkknJI3QMss
Channel Id: undefined
Length: 16min 18sec (978 seconds)
Published: Wed Jun 14 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.