Liskov Substitution Principle 🤔(Php SOLID Principles)
HTML-код
- Опубликовано: 30 сен 2024
- Liskov Substitution Principle
~~~~~~~~~~~~~~~~~~~~
#Liskov's #substitution principle, is a software design principle most totable as the L in #SOLID design principles.
Liskov, references Barbara Liskov ~ the creator of the substitution principle.
In 1987, Barbara Liskov introduced a mathematical formula used to determine if a parent class and child class, or an abstract and an implementation are substitutable with each other.
Her mathematical formula is a specific implementation of what is
known as "String behavioral sub-typing".
A classes "behavior" is defined by its methods or functions.
A child class inherits its behavior from its parent class, making the child a sub-type of the parent class.
A child class can override inherited parent behavior with its own behavior.
This means a child can define its own function that differs from its parent function.
When a child overrides a parent function with its own behavior, we are no longer certain that the child and parent are substitutable with each other throughout the entirety of our application.
Liskov's Substitution principle defines a set of rules the child function can abide by when overriding parent behavior to insure that the parent and child are substitutable.
Here are the 5 rules a child must abide by to insure it is substitutable with its parent when overriding parent behavior (Based on the mathematical formula behind Liskov's substitution principle).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 Rules when overriding a method within a child class
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Child method arguments must match parent method arguments
2. Method return type must match parent return types.
3. pre-conditions of child function cannot be greater than pre-conditions of parent function
4. post-conditions of child function cannot be lesser than post-conditions of parent function
5. Any exceptions the child throws must be the same or a child of the same exception thrown in the parent function.
Dive in with me, as we go through the Liskov Substitution Principle ~ from a higher level and then directly within Php. #Php #SOLID #DesignPrinciples #LiskovSubstitutionPrinciple #LSP
Clean Code Studio ~ Simplify!
Clean Code Clean Life
cleancode.studio
cleancode.stud...
Excellent video! note to other commenters: the point of liskov substitution principle has little to do with the inner working of the functions, rather that the classes all stay uniform so substitutions can occur without breaking the code.
Great tip!
bro rule 03 make me little confuse , any one can please tell me bit more
I still don't understand this, how would you validate the input (json/html) then?
Once there is an interface, each class could handle its validation. For instance, the validation can done while parsing the file and they would be done differently by each class.
When a class implements an interface, if just says that given class CAN parse.
Semantically, we would expect this class to parse HTML
class HtmlFile implements File
{
public function parse() { // should parse html }
}
and this class to parse JSON
class JsonFile implements File
{
public function parse() { // should parse json }
}
It's up to the engineer to actually implement the how within the parse function itself.
The rest of your application that digests or uses the File interface ~ will know that the passed in instance is able to parse but won't know how parse is actually implemented.
The rest of our application just depends on the fact that the instance CAN parse NOT on HOW it will parse.
I just re-read my response to this question and realized I answered you but not really with the question that you asked. My bad :)
To answer your question, we really can't validate that the input is Json or Html based on the principle itself. Within Php, we can build abstractions that are used to check if input really is Json or html ~ but, on a higher level, architectural we can't prove this.
That's not saying we shouldn't have an abstraction in place to prove input is qualified to indeed be the input we accept, but the Liskov Substitution Principle isn't responsible for orienting this proof. That's up to us, as the engineers, to prove we are correctly using JSON and Html.
If we wanted to add a validation method to check the file content or file extension, we could engulf that within the standards of the Principle and Demand every class have a file validation method....but that's completely up to you and your team.
Thank you for you details explanation for SOLID principle, especially you are using PHP!! looking forward your other software engineering topic!!
You're very welcome!
Mhm this is kinda tricky lol. Especially the pre conditions and post conditions
Yeah, SOLID principles are definitely one of the trickier concepts as a whole.
Do you have any specific questions that I can help out with?
*Preconditions* Happen Before A Function Runs
*Example:*
function (User $will) //
what if child has additional methods? then you cant substitute parent class
substitution usually works the other way round. children can substitute parent always. parent cannot sub child
Hey @Shez 1983 ~ GREAT question. The honest answer based on my personal understanding is that I didn't initially know off the bat. I actually asked your question on Reddit and got some descent feedback.
I haven't had a chance to do the research and back any claims within the thread, so I don't want to say with absolute certainty what the answer is to your question as of yet (When I get a chance, I'll look into it and get back to you), but here's the link to the Reddit thread I created specifically in reference to your question.
www.reddit.com/r/PHP/comments/ens2gc/i_understand_liksovs_substitution_is_a_definition/
very cool
Thanks Joshua, Liskov's substitution Principle ~ in my opinion ~ is the second most difficult SOLID principle. Liskov's Principle and the Dependency Inversion principle have plenty of brick walls.
Contrary to popular belief, brick walls are only destroyable via thousands of head punches.
@@CleanCodeStudio toally agree
The last example of File/Json i think you just simplified things - for example in the original parse func we had a check to make sure that file was json - when u refactored to an interface that check was gone - but i dont see why we shouldnt check that after you extracted things to interface etc. Also when you were having trouble deciding whether to call parse return type you again simplified but eventually we would need to return content of that file and then we would need to decide should the return of that method be array (for json) or string for (html) etc..
Well, after reviewing my own lesson....you're definitely not wrong ¯\_(ツ)_/¯
@@CleanCodeStudio thanks for replying.. a solution would be helpful as i am merely a newbie and constantly seeing dumbed down code is doing me head in.. :) thanks
@@Shez-dc3fn Forsure, I'll review it here in the next couple of days and get back with you
@@CleanCodeStudio thanks that will be appreciated..
Ok, kinda late to the party, but just explaining in a way that's more simplified for anyone having issues with this Principle:
Imagine you have a software that you call robots to make you coffee. But not all robots are available at the same time.
So here we have: John, Marc and Ross
John will always makes espresso
Marc will make cappuccinos
Ross will make black
Whenever you say "Robot, make me a coffee", no matter which Robot answers first , they will always bring you a coffee even if the types are different. The drinks are still coffees.
So, putting it into more technical terms: Whenever you write "$robot->coffee()", no matter which robot, the function will always execute and do something without throwing any errors (And we don't care what which class will do, just that it fulfills it's contract of bringing/making us the coffee). That's the Liksov Substitution for y'all
Your explanation of the Liskov Substitution Principle (LSP) using the robot coffee makers is spot on and a great way to simplify the concept. T
he essence of LSP is that objects of a superclass should be replaceable with objects of their subclasses without affecting the correctness of the program.
In other words, if you have a base class Robot, you should be able to substitute it with any subclass instance like John, Marc, or Ross, and the program should function correctly.
In your analogy:
- Superclass (Interface): Robot
- Subclasses: John, Marc, Ross
- Method: makeCoffee()
No matter which robot you use, calling makeCoffee() will result in a coffee being made, fulfilling the expected behavior.
amazing thank you for sharing
My pleasure!