Liskov Substitution Principle

Поділитися
Вставка
  • Опубліковано 31 тра 2024
  • Violating the 7 rules of the Liskov Substitution Principle (L in SOLID) leads to code that is difficult to reason about. The 3 type rules can be checked by compilers but the 4 behavioral rules have to be respected by us developers.
    ⭐️ More about LSP in Clean Architecture (Chapter 9): geni.us/IBhtLnh
    Watch First: • Covariance and Contrav...
    📄 The paper: dl.acm.org/doi/pdf/10.1145/19...
    🏛️ Design By Contract: en.wikipedia.org/wiki/Design_...
    CONTENTS
    00:00 Intro
    01:33 Formal Definition
    02:56 Robustness Principle
    06:09 Type Rules
    08:50 Terminology
    11:59 Behavioral rules
    19:15 Conclusion

КОМЕНТАРІ • 70

  • @MarkMifsud
    @MarkMifsud 17 днів тому +6

    Your explanations are long winded, but they are clear and that's why they are really helpful. Thanks.

    • @ChristopherOkhravi
      @ChristopherOkhravi  17 днів тому

      Please do let me know if you start to think that I'm becoming way too repetitive 😊 Thank you for watching and for the feedback 😊🙏

    • @michaelhaddad2190
      @michaelhaddad2190 17 днів тому +5

      @@ChristopherOkhravi Absolutly not. Every second of every video is gold.

    • @professorfontanez
      @professorfontanez 9 днів тому +1

      @@ChristopherOkhravi In this case, too repetitive is a good thing. It reinforces the message being conveyed. I am sure that your motivation was that this topic (LSP) is generally misunderstood by developers. One suggestion, if I may, instead of "weaker" and "stronger", use less restrictive and more restrictive respectively. It might be semantics, but I think wording everything in terms of "restrictions" might be clearer.

    • @FonzoUA
      @FonzoUA 2 дні тому

      @@ChristopherOkhravi I feel re-iterating same explanations but in other words (even if a bit long-winded) helps to get that "aha" moment that sometimes might be obfuscated by semantics.

  • @FritsvanDoorn
    @FritsvanDoorn 14 днів тому +4

    You make this difficult subject easy to understand. Thank you.

  • @waleedelwakeel5721
    @waleedelwakeel5721 17 днів тому +1

    That's amazing.
    I am always eager to understand pure concepts rather technology coupled ones. I appreciate your interest in that matter and you are truly killing it.
    Thank you for your efforts and I hope you continue sharing your great knowledge.

  • @ukcryptolondonbased2953
    @ukcryptolondonbased2953 7 днів тому

    This is the first time I've really appreciated the LSP and the implications of violating it. Would be nice to see some patterns to deal with situations where inheritance seems applicable but the LSP would be violated. Using a version of an example you used, say I had a third party class for some collection (i.e. I don't own the code) and I wanted to make an immutable version of it where the Clear method doesn't empty it.

  • @mufizshaikh8439
    @mufizshaikh8439 9 днів тому +1

    so good to hear from you after long time.! welcome back!

  • @demarcorr
    @demarcorr 17 днів тому +1

    covariance and contravariance are probably one of those things i understand subconsciously but can never seem wrap my head around consciously

  • @janvanwijk5979
    @janvanwijk5979 12 днів тому

    Another excellent video, thanks for making it! ❤

  • @greob
    @greob 18 днів тому +1

    Very nice presentation, easy to follow and understand. Thanks for sharing!

  • @silberwolfSR71
    @silberwolfSR71 18 днів тому +1

    Amazing video as usual!
    I think an interesting thing to point out is that many of these different "software design principles" complement each other, each making use of the others easier and more effective.
    For instance, preferring to code to interfaces makes adhering to the Liskov Substitution Principle much easier, because there are usually no invariants relating to state. Similarly, interface segregation leads to small interfaces, whose invariants are easier to grasp and enforce. Sharing code through composition rather than inheritance bypasses substitution concerns entirely, since there's no subtyping involved.

    • @ChristopherOkhravi
      @ChristopherOkhravi  18 днів тому +2

      Indeed. I very much agree. Thanks for pointing this out 😊🙏 And thanks for watching 😊

  • @javiermorin3110
    @javiermorin3110 17 днів тому

    I love all your videos! Thank you so much for taking the time to make them!

  • @nullcheque
    @nullcheque 18 днів тому

    Before I even finish this video-big thank you for the Elegant Objects recommendation in your other video about Always Using Interfaces. I am about halfway through the book, and in conjunction with your content about coupling to abstractions, my understanding and use of OOP has already begun greatly improving the code I write at work.

  • @Wojmasz
    @Wojmasz 17 днів тому

    great piece of knowledge! thank you!

  • @johncerpa3782
    @johncerpa3782 17 днів тому

    Great video, thank u

  • @sharpfang
    @sharpfang 6 днів тому

    I wonder here now, if I need a type T which violates the LSP if set as subtype of pre-existing type P, would modifying the hierarchy and changing P to be a subtype of S, and S to be subtype of whatever P was a subtype of (and not violating LSP here), is a good move. For example, make pre-existing List a subtype of newly-created UniqueList.

  • @etodemerzel1011
    @etodemerzel1011 9 днів тому

    Un gustazo escucharte

  • @amerbashoeb2106
    @amerbashoeb2106 18 днів тому

    Thank you!

  • @filippobuonco95
    @filippobuonco95 18 днів тому

    Lovely! Thanks for this video! I have a question, is a violation of the LP if a method in the subclass accept more parameters (meaning not a bigger range of values of the parameter, but really the number of parameters the method is getting as input) than the method in the superclass?

    • @ChristopherOkhravi
      @ChristopherOkhravi  18 днів тому +2

      Thank you for the detailed question. In my reading I would say that more parameters is not a violation as long as it still can be called just like you can call the super class. So the additional parameters would have to be optional for this to work. Otherwise this is actually not being liberal but rather being conservative. Off the top of my head I cannot however think of languages that would support this. Did you have some language or example in mind?
      Thank you again 😊🙏

    • @Robert-yw5ms
      @Robert-yw5ms 17 днів тому

      @@ChristopherOkhravi Javascript supports this without issue.
      class Parent {
      foo(x) { console.log(x) }
      }
      class Child extends Parent {
      foo(x,y) { console.log(x,y) }
      }
      new Child().foo(1,2);
      Although in a sense the parent foo method will also accept any number of arguments. It'll just ignore the extra ones. It will also accept fewer parameters and treat x as undefined.
      I'd also say that adding overloads with different parameter counts in c# or java is another example. Which clearly doesn't break LSP.

    • @ChristopherOkhravi
      @ChristopherOkhravi  17 днів тому +1

      @@Robert-yw5ms Silly of me to not immediately think of JavaScript 😊😊Thank you for the reply.
      Overloading however does not need to respect LSP. LSP applies when we are overriding, or more generally: when we have dynamic dispatch as a consequence of subtype polymorphism. So in other words, interface implementation (in languages like C# and Java) also needs to respect LSP.

    • @Robert-yw5ms
      @Robert-yw5ms 17 днів тому

      ​@@ChristopherOkhravi Although it is worth noting that this is one of many issues with javascript that typescript fixes. I hope people don't read my comment and think "oh amazing let's do that" :D
      And I agree completely with your second paragraph.

  • @grossd18
    @grossd18 18 днів тому

    Can it be worthwhile to apply these principles to interface evolution, when a need for backwards compatibility is desireable. It seems that yes, it could apply.

  • @bogdanf6698
    @bogdanf6698 17 днів тому

    comment for support! thanks! I'll get back here in 2 years :D after I have learned enough to understand the explication

  • @PixelSergey
    @PixelSergey 18 днів тому

    Interesting! How would one implement classes such as UniqueList or ImmutableList while still following these principles? It seems so natural to just write a bunch of code for a base List class, and then just make a subclass that inherits this code but adds extra checks (for immutability or uniqueness). How do we do this in other ways?

    • @Robert-yw5ms
      @Robert-yw5ms 17 днів тому

      Simple: don't inherit from list. But there's nothing stopping you using a list as a backing field

  • @detaaditya6237
    @detaaditya6237 18 днів тому

    Wow I never thought Postel's Law is related with LSP. It makes a lot of sense, though!

  • @wilkesreid
    @wilkesreid 17 днів тому

    This seems kind of obvious to me. If B is a subclass of A and “x” is an instance of some subclass of A, and you could have x.fido() calls anywhere, then it would be utter chaos because x could be an instance of B in any of those places and B could have overridden fido to behave so differently that your code can’t know what to expect as a result of x.fido() because it could be anything. If I expect x.fido() to return an array, then an array of objects, or array of ints is fine, but of course you shouldn’t override it to return an object or some struct. And if the arguments given to x.fido() could be any integer, then of course you shouldn’t reject whatever would normally be acceptable to A for that method.

  • @tibrec8
    @tibrec8 17 днів тому

    nice as always bro , can make technical practice video for this .

    • @ChristopherOkhravi
      @ChristopherOkhravi  12 днів тому +1

      Thank you for the feedback. I will think about how to make my content more concrete in the future. Screencasts is a very saturated niche so I’m very hesitant towards entering that game again 😊

  • @user-ev9jg6ts6e
    @user-ev9jg6ts6e 13 днів тому

    Excellent as always. How soon will you publish your own book?)

    • @ChristopherOkhravi
      @ChristopherOkhravi  11 днів тому

      It's already 'published' 😊 I wrote a book on OOP and it's currently available for free at theobjectorientedway.com. It moves from the very basics (like variables) to fairly advanced concepts (like variance in generic interfaces).
      Thanks for asking 😊

    • @user-ev9jg6ts6e
      @user-ev9jg6ts6e 11 днів тому

      @@ChristopherOkhravi Wow, wonderful) I'll take a look) Thanks.

    • @user-ev9jg6ts6e
      @user-ev9jg6ts6e 11 днів тому

      @@ChristopherOkhravi Do you have a PDF of the book?

  • @peteralexandre6593
    @peteralexandre6593 18 днів тому

    Thanks for this amazing content. It might be dumb to ask but being a non native english speaker what is this word you are using in a lot of your videos wich sounds like "hirokee" ? Need to know how to spell it to search for the definition 😅

    • @ChristopherOkhravi
      @ChristopherOkhravi  18 днів тому +3

      I think you are referring to “hierarchy”, no? Do note that all my new videos have accurate closed captions. So be sure to turn those on if you find the way I speak confusing. Which is understandable since I’m not a native English speaker either 😊😊😊 Thank you for watching and for asking. 😊🙏

    • @peteralexandre6593
      @peteralexandre6593 18 днів тому

      Yeah that's hierarchy thank you so much. No no your English accent is perfect I understand 99% of your videos even without captions it's just that I was not used to the word hierarchy in English. See, you make me a better developer and make me improve my English at the same time. Thanks again.😊

  • @pixaz
    @pixaz 18 днів тому

    14:33 the same argument could be made when you say same or weaker precondition.
    If we have a base type of UniqueListBase with a precondition, on the Add method that you cannot add duplicates, and subtype of UniqueListDerived that isnt restricting the uniqueness. That would also be a violation of liskov no?
    if somewhere down the road, people are using UniqueListDerived as a UniqueList, it might cause them problem

    • @ChristopherOkhravi
      @ChristopherOkhravi  18 днів тому +3

      I think I understand what you mean but tell me if it seems like I don’t. According to LSP, the example you give would not be a violation. It is ok to make preconditions weaker. So if the subtype wants to get rid of the requirement that we cannot add items that are already in the list that would be perfectly fine.
      If you however have a postcondition or an invariant that says that items may not be duplicated in the list then that cannot be weakened in the subtype. And if your base type is called UniqueList then it would (imho) make sense for us to think of it as having postconditions or invariants enforcing uniqueness of elements.
      Makes sense?
      Thanks for the detailed comment and for watching 😊🙏

    • @pixaz
      @pixaz 18 днів тому

      @@ChristopherOkhravi oh i seeee! thanks for the response!

  • @albertwang5974
    @albertwang5974 16 днів тому

    Don't be a trouble maker, and don't fail if you have to work with a trouble maker!

  • @alejandroioio6784
    @alejandroioio6784 16 днів тому

    😎

  • @ReviewSutras
    @ReviewSutras 18 днів тому

    Can we have examples?

    • @ChristopherOkhravi
      @ChristopherOkhravi  12 днів тому +1

      Thank you for the question and for the feedback. Would it be possible to elaborate a bit? I give examples in the sections on Terminology (8:50) and Behavioral rules (11:59). But it seems that you are looking for something else. Thanks again for the feedback and for watching 😊😊

    • @ReviewSutras
      @ReviewSutras 12 днів тому

      @@ChristopherOkhravi Thanks for your response. Example in the sense, with a sample class in java, we try to see things in action.

  • @albertwang5974
    @albertwang5974 16 днів тому

    Be a nice guy, and don't expect every one will be a nice guy!

  • @RobertShresthawolf
    @RobertShresthawolf 18 днів тому +1

    First one here :)

  • @mortenbork6249
    @mortenbork6249 18 днів тому +4

    If you use composition over inheritance, and DI with interfaces, and not types. You can't violate LSP, because the rules are inherently followed. This is actually one of the reasons that composition is better than inheritance.

    • @Robert-yw5ms
      @Robert-yw5ms 17 днів тому +2

      This is wrong. Every interface exposes a contract. When you implement that interface, you have to fulfill that contract. Otherwise you're breaking the lsp. Example you have an interface IStack with the normal stack methods and you then implement it in a FIFO way. You've just broken lsp.

    • @TuxCommander
      @TuxCommander 17 днів тому

      Wrong. You literally ignoring the fundamental aspect of LSP.
      As stated in the video, it's mainly about behaviour not design which would be detected by the compiler.

    • @mortenbork6249
      @mortenbork6249 17 днів тому

      ​@@Robert-yw5ms
      And your compiler will prevent you from not fulfilling the contract.
      You can't break it.

    • @Robert-yw5ms
      @Robert-yw5ms 17 днів тому

      @@mortenbork6249 It won't prevent you from breaking the behavioural contract. Read the example I gave and try to understand it.

    • @Robert-yw5ms
      @Robert-yw5ms 17 днів тому +1

      @@mortenbork6249 Type definitions are only one part of the contract. Behaviour is the other. Read the example I gave and try to understand it. Or watc the video from 12 minutes. Each interface promises to have certain preconditions, post conditions and invariants.

  • @ajzack983
    @ajzack983 16 днів тому +1

    Liberal is weaker, conservative is stronger.
    Got it.