@@WebDevSimplified hey, how are you able to reassign the variables in the class that aren’t ever declared? @6:07 I see ‘this.description’ and ‘this.options’ but declared no where. Is it that in that one line, it’s being created as a member variable for the class and instantiated without any declaration keywords?? Thank you 🙏🏽
two months ago i made a project using php and js for stock managing , the result i was satisfied with but i had to remake the project like four times , the longer i code the more complicated the code gets and i reached the point of forgetting what code i am writing while i am writing it , and it was exactly the SOLID design principles what i was missing writing a function that takes data, process it, do the logic, and modify the dom and even sending queries is nutttttts , i figured that out the hard way , if only i read about this before
It may be good to note that in Java you should program to an interface. This means that each of the question types would implement that interface (Let's say Question interface). Implementing the interface creates a "contract" which states that each of the implementing classes MUST have a "printQuestionChoices()" method, regardless of how that implementing class chooses to implement it. Then your printQuiz() method would take an object of the Question type as a parameter. By implementing the interface, each implementing class becomes of that type and therefor can be passed to printQuiz()
@@danielmyers9580 An interface might make more sense in this scenario than a base Question class. Sure, it can work, but an interface would likely be a lighter weight and simpler way of achieving the same thing. The choice between using a base class and an interface depends heavily on the requirements of the program. An interface simply states which methods an inheriting class must implement, without any requirements on how to run that method (outside of the method signature. Those have to match in order for it to be valid). A base class can work better if inheriting classes are going to share similar or the same implementation details. If the implementation is going to vary quite a bit, an interface might make more sense. A base class can still inherit from an interface to help guide its implementation. I hope that helps. I don't know the specifics of the java language, but I'm speaking from my limited experience working with c#, which has many of the same features as java.
As someone else pointed out below, it might be better to have a base QuizQuestion class that has a description property and a default implementation of the printQuestion() function.. All the question types can extend from that base QuizQuestion class and provide a custom implementation of the printQuestion() function inherited from the base class.
I'm glad you're taking the time to cover all of these principles. I've just learned about SOLID today, so I'm taking the time to learn about it. The biggest struggle I always have when working on new projects is deciding how to structure things. What often happens is I'll get halfway through a project, decide to add/remove some functionality, and have to spend so much time sifting through my code to correct all the errors that inevitably pop up.
After many videos, I found the best explanation and best teaching for this principle, I have seen a lot of your videos, and your teaching method and enthusiasm is at the highest level, thank you Kyle!
I'm Brazilian, and man it's easy to understand even with my low fluency in english contratulations! When you choose to explain the OCP with an example makes the knowlegde of this complex *#&@#& more palpaple. Thx again
These videos are priceless. I totally understand the open closed principle now. Perfect explanations. But for me the Liskov principle is just as difficult to understand. Please do a vid about that. Thank you again.
thank you so much, that makes it so much easier to understand. If I understand correctly, that means your program should be able to be extended without modifying it. As modifying a class can modify it's functionality with other dependencies, but if we just extend the class, it will not affect those dependencies.
Good example 👍. If it was typescript, I would have interfaces to make sure the question classes obey the right structure / signature 🤓 - similar to the Adapter pattern you have share before
I've never heard about these SOLID design principles but they are simply great. Thank you! Could not find is some asked this already. But if question object, in questions array, contains all neccessary messages that need to be printed (like question.type, question.description there could be question.answers). This would allow us to skip entirely creating new classes and whole script would be made out of two parts: question array and function that prints out questions with answer fields. tl;tr. Add question.answers field that contains all expected answer messages (remove questions.type no use at this point). In printQuiz() function loop through array: print question description and print expected answers.
For YEARS I've been trying to understand this one, finally I do! Makes perfect sense now, especially for use with interfaces in Java. Thanks very much, Kyle
Nice! Good, simple explanation. Sometimes the definitions of concepts like this assumes so much about the user's existing knowledge, so breaking things down like this is very helpful. Thanks!
Hi! Thanks for easy explanation! It's really great.. But, I have question.. When I see the code in array, it make sense. But... When I try to think about the data from database. How do we process this? I mean... When we receive data from database, it's not class based, but type based. And we need to convert that type into our class like in your tutorial. And on that process, we still use if / switch statement right? Am I wrong? And.... If we still use if / switch to declare the class, is it still labeled as open close? Because we directly modified the code even if it's just converting the data. Thank you...
great explanations , but I think it would be better to have a super class Question with the common constructor and extend other classed from that class , this will be better . Great efforts , thanks a lot for your time and efforts
Great approach, only thing I would change is the use of classes. You can can do the same implementation but with currying: const textQuestion = (description) => { return () => { console.log('Answer: _____________') } }
Great work! Love when people use useful examples instead of cars, toys or shapes 😂 I have a question however. Whenever this example of the switch statement arises, or other open/close example, usually we reach out for classes to solve the problem. Following the "Single Responsibility" principle, the question itself should be responsible for doing whatever it wants. I was wondering how this will be solved when dealing with a more functional approach. Would you use callbacks or something similar?
Although Kyle shows great example of OOP via class implementation. On other hand, callbacks, as @Chaos mentioned, I guess would be more functional approach. But do we really need all this "fancy OOP stuff". Question object could have another field that could store messages of expected answers and function printQuiz would be only responsible for printing. No classes, no question type checking via switch or ifs (we dont need question type at all), no extra functions (callbacks) just loop through array print question's description and question's expected answers. question.description = "Speed limit in your city?"; question.expectedAnswers = [ "Minimum value: ", "Maximum value: " ];
What is more, i feel like the OOP solution he used doesn't actually get rid of the switch statement he is talking about, in this example he changed a simple data structure that could be sent via ajax for example into class initializations in the code, but if the questions come from the server, he'd still need to go through a switch statement to initialize each question to its adequate type, i feel like the functional approach would be simpler and cleaner, and there is nothing wrong with a switch statement if placed correctly
I understood and I liked how you explained with js and one bad point that I can see with js is because we cannot declare interfaces to be implemented and then we need to make sure that the name of the method is really the same between those classes and having an interface to declare this method would be better because we could create RangeQuestion class implementing idk "PrintableOption" class in order to not worry about writing the method with the same name
Another way to handle this would be with the visitor pattern. It has the added benefit of separating data and rendering which is really handy if you want to have multiple ways of rendering output for different user interfaces. I'm still new to applying the open/closed principle consciously. The visitor pattern allows the outer rendering loop to stay the same (open/closed), but everytime a new type is added, the visitor needs updating too which violates open/closed in my understanding.
Yes. But but these principles are not strict rules. They are there to help us to organize code. It is Ok to break those principles if the benefit outweighs the disadvantages. The reducer's switches usually have very minimum logic, so it is preferable compared to writing separate classes for each of them.
Nice explanation, you could also make each of the individual question classes inherit from a ‘base question’ which inside it would have the print function, meaning you would never forget to include the print as it wouldn’t compile without it.
Alireza M you are kind of right but there is something called ‘Prototype Inheritance’ in JavaScript that will do the job. I probably should of worded my comment better to say that languages that support it could use inheritance, as SOLID is used across many languages not just JavaScript, it just happens to be Javascript that was used in this example.
Is it just me or does this seem more like a Liskov Substitution sample? I think Open-Close is more for extending the functionality of a call without changing the main class. For this, I'd make use of the "extends" key word. Still this was really well explained.
What if the method requires different arguments to achieve its functionality? Then how would we implement that? Surely we wouldn’t know what to pass in ? Your great btw Kyle.
thanks for the great example explaining open closed principle. the following question is what about c++ example since c++ cannot put objects of different classes into an array?
Hi Kyle! One Question, your new implementation, to me it looks like a perfect example of the Factory Pattern, am I right with my assumption or would you disagree? I am getting my head around design patterns atm. I guess the only thing missing would be the abstract method of a parent class that would force the child classes to implement the printQuestionChoices method
The idea is when we have heterogeneous types of output paths in our code for a given function, by definition of open-close principle, this function should be open to adding more paths, but closed from the code being modified. The idea is to make a class for each of the different path, but all the classes are based on a common contract ( printAnswrChoices() in this example ), which is something used in the original function on which the Open close principle applies to. All these classes also adhere to the Single Responsibility pattern :) Essentially inheritance in Java is a very good example of the same.
Great video as always! Thanks for all that you do, this is such a great concept. I’d love to hear your thoughts on all things Typescript. Do you feel that it influences JS dev’s architecture in favor of a more OOP driven design. Have you used it? What do you think of it?
Thanks brother. Im was confusing before using this principle. When I add new feature or my project getting bigger, it must be found some little bug as you told, and its hard to realize.
Please keep going with SOLID. So useful actually and I'm improving on my code so much!
I am planning to record the next letter tonight!
Wonderful!
@@WebDevSimplified I would also recommend to put a playlist link, so it's clearer which videos are about that
@@WebDevSimplified hey, how are you able to reassign the variables in the class that aren’t ever declared? @6:07 I see ‘this.description’ and ‘this.options’ but declared no where. Is it that in that one line, it’s being created as a member variable for the class and instantiated without any declaration keywords??
Thank you 🙏🏽
Clients be like can this be done by Friday?
Me: There goes my SOLID principle.
that's what happens when project managers are yes men/women
@@XavierGoncalves89 Could not possibly agree more
you, my friend, has just reached the next level of teaching...
In 10 minutes you succeeded in what a college teacher failed to do in 6 months. Thanks!
I love your videos. I get so relaxed I fall asleep and have to re-watch. You're not boring, it's your voice I'm so in love with it.
100k LETS GOO
Ed? 😮
Vi
Only 2K right now :(
Was at 100k 4 years ago? Wow!
I'll leave this here, for the next person 4 years from now.
1.5M LETS GOO
two months ago i made a project using php and js for stock managing , the result i was satisfied with but i had to remake the project like four times , the longer i code the more complicated the code gets and i reached the point of forgetting what code i am writing while i am writing it , and it was exactly the SOLID design principles what i was missing
writing a function that takes data, process it, do the logic, and modify the dom and even sending queries is nutttttts , i figured that out the hard way , if only i read about this before
It may be good to note that in Java you should program to an interface. This means that each of the question types would implement that interface (Let's say Question interface). Implementing the interface creates a "contract" which states that each of the implementing classes MUST have a "printQuestionChoices()" method, regardless of how that implementing class chooses to implement it.
Then your printQuiz() method would take an object of the Question type as a parameter. By implementing the interface, each implementing class becomes of that type and therefor can be passed to printQuiz()
what about having a Question class, and then Boolean extends Question, MultiplChoice extends Question, TrueFalse extends Question, etc.
Question would be closed to modification but open to extension
@@danielmyers9580 An interface might make more sense in this scenario than a base Question class. Sure, it can work, but an interface would likely be a lighter weight and simpler way of achieving the same thing. The choice between using a base class and an interface depends heavily on the requirements of the program.
An interface simply states which methods an inheriting class must implement, without any requirements on how to run that method (outside of the method signature. Those have to match in order for it to be valid).
A base class can work better if inheriting classes are going to share similar or the same implementation details. If the implementation is going to vary quite a bit, an interface might make more sense. A base class can still inherit from an interface to help guide its implementation.
I hope that helps. I don't know the specifics of the java language, but I'm speaking from my limited experience working with c#, which has many of the same features as java.
This question is really common on job interviews. Thanks for this. Keep up the good work.
As someone else pointed out below, it might be better to have a base QuizQuestion class that has a description property and a default implementation of the printQuestion() function.. All the question types can extend from that base QuizQuestion class and provide a custom implementation of the printQuestion() function inherited from the base class.
It has to be an interface.
nope, it doesn't
Seems to me he’s going by the pattern of composition over inheritance here
I'm glad you're taking the time to cover all of these principles. I've just learned about SOLID today, so I'm taking the time to learn about it. The biggest struggle I always have when working on new projects is deciding how to structure things. What often happens is I'll get halfway through a project, decide to add/remove some functionality, and have to spend so much time sifting through my code to correct all the errors that inevitably pop up.
I am running into this, too. I typically try to restart, and get 20% farther and then it happens all again.
After many videos, I found the best explanation and best teaching for this principle,
I have seen a lot of your videos,
and your teaching method and enthusiasm is at the highest level,
thank you Kyle!
Thank you for showing on top of my search result and NOT speaking Hindi. You deserves my like and subscription.
I'm Brazilian, and man it's easy to understand even with my low fluency in english contratulations! When you choose to explain the OCP with an example makes the knowlegde of this complex *#&@#& more palpaple.
Thx again
These videos are priceless. I totally understand the open closed principle now. Perfect explanations. But for me the Liskov principle is just as difficult to understand. Please do a vid about that. Thank you again.
thank you so much, that makes it so much easier to understand.
If I understand correctly, that means your program should be able to be extended without modifying it. As modifying a class can modify it's functionality with other dependencies, but if we just extend the class, it will not affect those dependencies.
I'm so glad you're going over the SOLID principles. One is pretty much guaranteed to be asked about one in a software dev interview.
Good example 👍. If it was typescript, I would have interfaces to make sure the question classes obey the right structure / signature 🤓 - similar to the Adapter pattern you have share before
@Eddie Jaoude how is this related to adaptor pattern ?
I've never heard about these SOLID design principles but they are simply great. Thank you!
Could not find is some asked this already. But if question object, in questions array, contains all neccessary messages that need to be printed (like question.type, question.description there could be question.answers). This would allow us to skip entirely creating new classes and whole script would be made out of two parts: question array and function that prints out questions with answer fields.
tl;tr. Add question.answers field that contains all expected answer messages (remove questions.type no use at this point). In printQuiz() function loop through array: print question description and print expected answers.
this channel and net ninja have changed my programming life
I think I finally understand this principle after reading about it numerous times over the years and watching other videos. Good example, thanks!
I wanna cry how beuatiful you explained all of it
This is the best explanation of this principle on the internet. Thank you so much man!!!
Thank you Kyle you'r vids are perfect I encourage you to never stop teaching, hope the best.
Best explanation of the concept, and I searched quite a bit.
I was always doing the switch statement but it felt so wrong! I watch your videos daily, THANKS 🙏
Best Open/Closed explanation and example I have seen. So simple! Thanks!
For YEARS I've been trying to understand this one, finally I do! Makes perfect sense now, especially for use with interfaces in Java. Thanks very much, Kyle
Excellent Video! This is the best O/C principle video I have seen. Please continue making Design Pattern videos.
hands down one the best no bullshit programming channels!
so underrated !! this is great and really useful in complex projects
Nice! Good, simple explanation. Sometimes the definitions of concepts like this assumes so much about the user's existing knowledge, so breaking things down like this is very helpful. Thanks!
Thank You So Much for this wonderful video................🙏🏻🙏🏻🙏🏻🙏🏻🙏🏻🙏🏻
This was really well explained, thank you so much for the clear explanation. I am definitely going to watch the remaining videos you did on SOLID
This is a good explanation of O/C principle
Thank u so much for explaining in simple ways👍
Hi! Thanks for easy explanation! It's really great.. But, I have question.. When I see the code in array, it make sense. But... When I try to think about the data from database. How do we process this?
I mean... When we receive data from database, it's not class based, but type based. And we need to convert that type into our class like in your tutorial. And on that process, we still use if / switch statement right? Am I wrong?
And.... If we still use if / switch to declare the class, is it still labeled as open close? Because we directly modified the code even if it's just converting the data.
Thank you...
You are an excellent teacher.
great explanations , but I think it would be better to have a super class Question with the common constructor and extend other classed from that class , this will be better .
Great efforts , thanks a lot for your time and efforts
Wow.. 100K.. Congrats Sir Kyle. I'm happy for you and thanks for the content.
Thank you so much! I cannot believe so many people find my videos useful and educational.
These videos are great. I am just sorry that there are no repos as there were for the design patterns series. Thanks a lot Kyle.
Your Videos are superb.
Kindly add one thing. Which is publish the code on Github. Before and after SOLID Principles.
Great explanation and the example shown here. Love it
you was amazing, very easy to learn with your explanation, congrats bro.
Awesome! You explained it in a way that is easy to understand. Thanks!
Thank you AGAIN and AGAIN for this simple, understandable video !! ^^
Everytime i want to make my code cleaner and simplier, I go to WDS. Thanks Kyle!
Very good explanation! Thanks, it helped me!
This exactly the problem i am having. Thank you so much.
1:06 that moment when you are so confident that you say about wikipedia's definition "sucks" XD
keep up the good job mate :D
Like he wanted us to use THIS tutorial
Thank you so much for the clear explanation!
Great approach, only thing I would change is the use of classes. You can can do the same implementation but with currying:
const textQuestion = (description) => {
return () => {
console.log('Answer: _____________')
}
}
Great work! Love when people use useful examples instead of cars, toys or shapes 😂
I have a question however. Whenever this example of the switch statement arises, or other open/close example, usually we reach out for classes to solve the problem. Following the "Single Responsibility" principle, the question itself should be responsible for doing whatever it wants. I was wondering how this will be solved when dealing with a more functional approach. Would you use callbacks or something similar?
I thought at first that he was going to add a callback in each question object,
I think this is the functional way of doing so.
Although Kyle shows great example of OOP via class implementation. On other hand, callbacks, as @Chaos mentioned, I guess would be more functional approach. But do we really need all this "fancy OOP stuff".
Question object could have another field that could store messages of expected answers and function printQuiz would be only responsible for printing. No classes, no question type checking via switch or ifs (we dont need question type at all), no extra functions (callbacks) just loop through array print question's description and question's expected answers.
question.description = "Speed limit in your city?";
question.expectedAnswers = [ "Minimum value: ", "Maximum value: " ];
What is more, i feel like the OOP solution he used doesn't actually get rid of the switch statement he is talking about, in this example he changed a simple data structure that could be sent via ajax for example into class initializations in the code, but if the questions come from the server, he'd still need to go through a switch statement to initialize each question to its adequate type, i feel like the functional approach would be simpler and cleaner, and there is nothing wrong with a switch statement if placed correctly
CTRL-F
"switch"
1309 occurrences found
🤔
I understood and I liked how you explained with js and one bad point that I can see with js is because we cannot declare interfaces to be implemented and then we need to make sure that the name of the method is really the same between those classes and having an interface to declare this method would be better because we could create RangeQuestion class implementing idk "PrintableOption" class in order to not worry about writing the method with the same name
Another lit explanation! Thanks very much for making it easy to understand!
Great video, for sure very useful for many 👏👏👏, thanks and keep doing this great work 👏👏👏
Another way to handle this would be with the visitor pattern. It has the added benefit of separating data and rendering which is really handy if you want to have multiple ways of rendering output for different user interfaces.
I'm still new to applying the open/closed principle consciously. The visitor pattern allows the outer rendering loop to stay the same (open/closed), but everytime a new type is added, the visitor needs updating too which violates open/closed in my understanding.
Excelent video, now I understand better.
The explanation is brilliant
I don't know which is better: your hair or the way you describe SOLID. My thumb goes for both I guess.
Question: would a reducer function in Redux or React's useReducer be breaking this principle if we are using a switch statement for the action types?
I have the same question
interesting
Yes, it does. You'd have to do some other things to make it obey the SOLID principles. There are some videos on SOLID in React if that's of interest.
Yes.
But but these principles are not strict rules. They are there to help us to organize code. It is Ok to break those principles if the benefit outweighs the disadvantages.
The reducer's switches usually have very minimum logic, so it is preferable compared to writing separate classes for each of them.
This is really good. Thanks for sharing 👌👌
Learned a lot, thank you!
Nice explanation, you could also make each of the individual question classes inherit from a ‘base question’ which inside it would have the print function, meaning you would never forget to include the print as it wouldn’t compile without it.
In Scripting languages , it will not be necessary to do. Duck typing just kicks in.
I'm not sure, but I thought Javascript doesn't support inheritance?
Alireza M you are kind of right but there is something called ‘Prototype Inheritance’ in JavaScript that will do the job. I probably should of worded my comment better to say that languages that support it could use inheritance, as SOLID is used across many languages not just JavaScript, it just happens to be Javascript that was used in this example.
That's a genius explanation!!
i thought the extend part is somewhat related to inheritance. thanks for a clear explanation and a very good example.
Excellent Explanation.
Is it just me or does this seem more like a Liskov Substitution sample? I think Open-Close is more for extending the functionality of a call without changing the main class. For this, I'd make use of the "extends" key word. Still this was really well explained.
This was helpful. Thank you so much!
Great example and explaining
What if the method requires different arguments to achieve its functionality? Then how would we implement that? Surely we wouldn’t know what to pass in ? Your great btw Kyle.
This was really clear, very clever example, Thanks!
Great explanation, Thanks.
thanks for the great example explaining open closed principle.
the following question is what about c++ example since c++ cannot put objects of different classes into an array?
i really appreciate your efforts !! thanks a lot
wow the best ive seen so far !
I thought I knew the open/closed principle, but I did not. But now I do :)
Awesome explanation!
your sample code is amazing, I'd really appreciate it's elegant logic.
Hi Kyle! One Question, your new implementation, to me it looks like a perfect example of the Factory Pattern, am I right with my assumption or would you disagree? I am getting my head around design patterns atm. I guess the only thing missing would be the abstract method of a parent class that would force the child classes to implement the printQuestionChoices method
Awesome explanation 👍
Best explanation ever!
Woow thanks for the simple explanation.In this scenario do we need to create a base class with printqestionoption method and override that method
fantastic explanation. Thanks a lot Kyle!
Amazing video and amazing series! Definitely earned my sub.
The idea is when we have heterogeneous types of output paths in our code for a given function, by definition of open-close principle, this function should be open to adding more paths, but closed from the code being modified.
The idea is to make a class for each of the different path, but all the classes are based on a common contract ( printAnswrChoices() in this example ), which is something used in the original function on which the Open close principle applies to. All these classes also adhere to the Single Responsibility pattern :)
Essentially inheritance in Java is a very good example of the same.
very thanks! I understand very well
Huge thanks! Another great video.
Great video as always! Thanks for all that you do, this is such a great concept.
I’d love to hear your thoughts on all things Typescript. Do you feel that it influences JS dev’s architecture in favor of a more OOP driven design. Have you used it? What do you think of it?
Awesome explanation.!
You are a freaking genius.
woww, really great exaplanation!! thanksss
brilliant explanation. thank you
Very helpful, thank you!
greetings for 100K 🎉🎉🥳🥳🥳
I swear it's such a perfect video .. You are cool mate.. Thanks a lot
Very good example
Thanks brother. Im was confusing before using this principle. When I add new feature or my project getting bigger, it must be found some little bug as you told, and its hard to realize.
Superb explanation. Thanks c: