Liskov Substitution Principle

Поделиться
HTML-код
  • Опубликовано: 1 фев 2025

Комментарии • 84

  • @jiteshagrawal681
    @jiteshagrawal681 5 месяцев назад +8

    finally something that is not just copy paste of other articles or videos, Almost every article I have read on this give at max one example , some 4-5 statements repeated everywhere and that's it barely scratching the surface of the concept. Thanks @Christopher for making this amazing content and explaining it by deep dive

    • @ChristopherOkhravi
      @ChristopherOkhravi  5 месяцев назад

      Thanks for sharing this with me. Happy to hear that it’s useful 😊🙏

  • @sunnykumarsingh7039
    @sunnykumarsingh7039 7 месяцев назад +3

    Video is wonderful. Please continue with this series for SOLID principles Chris.

  • @MarkMifsud
    @MarkMifsud 8 месяцев назад +9

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

    • @ChristopherOkhravi
      @ChristopherOkhravi  8 месяцев назад

      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 8 месяцев назад +5

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

    • @professorfontanez
      @professorfontanez 8 месяцев назад +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 8 месяцев назад +1

      @@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.

    • @ChristopherOkhravi
      @ChristopherOkhravi  2 месяца назад

      @@FonzoUA Happy to hear that. I tend to very much agree.

  • @nullcheque
    @nullcheque 8 месяцев назад +2

    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.

    • @ChristopherOkhravi
      @ChristopherOkhravi  8 месяцев назад

      Happy to hear 😊 Thanks for letting me know 😊🙏

  • @waleedelwakeel5721
    @waleedelwakeel5721 8 месяцев назад +4

    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.

  • @mufizshaikh8439
    @mufizshaikh8439 8 месяцев назад +2

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

  • @sid2x
    @sid2x 3 месяца назад

    Good to see you back.😊

  • @silberwolfSR71
    @silberwolfSR71 8 месяцев назад +2

    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  8 месяцев назад +2

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

  • @rembautimes8808
    @rembautimes8808 4 месяца назад

    Excellent video - thanks for making and sharing. A lot of use cases

  • @peddiashrith
    @peddiashrith 6 месяцев назад +1

    Beautifully explained!!

  • @javiermorin3110
    @javiermorin3110 8 месяцев назад

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

  • @FritsvanDoorn
    @FritsvanDoorn 8 месяцев назад +5

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

  • @Meninafernanda
    @Meninafernanda 2 месяца назад

    Thank you for this content!

  • @demarcorr
    @demarcorr 8 месяцев назад +3

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

  • @ukcryptolondonbased2953
    @ukcryptolondonbased2953 8 месяцев назад

    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.

  • @Stop_Making_Sense1
    @Stop_Making_Sense1 5 месяцев назад

    Great lecture, just one comment: you should emphasize that immutable list in java is legal subtype of list, because there is a defined contract (in the list) that states that you should either add an element to the list and return true or you should throw an exception if it's not possible (never return false and ignore adding an element).
    Problem is that contract for add() in the list is not what we thing it is.

  • @janvanwijk5979
    @janvanwijk5979 8 месяцев назад

    Another excellent video, thanks for making it! ❤

  • @JCCyC
    @JCCyC 7 месяцев назад +2

    Sounds more like a quantum physics thing than a software development thing, to be frank. Which is awesome.

  • @Wojmasz
    @Wojmasz 8 месяцев назад

    great piece of knowledge! thank you!

  • @xwtek3505
    @xwtek3505 7 месяцев назад

    The thing is LSP often hides behind something that does not look like a subclass. For example, in Haskell, LSP is an important principle when using lens. This appears strange since Haskell isn't even OOP and lens are just a function from a profunctor to a profunctor. But lens actually has a subtyping hierarchy that has to be respected.

  • @tadeogonzalezalvarez6488
    @tadeogonzalezalvarez6488 6 месяцев назад

    In languages ​​like Java, does contravariance really exist in method parameters? It conflicts with method overloading.

  • @BlindVirtuoso
    @BlindVirtuoso 8 месяцев назад

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

    • @ChristopherOkhravi
      @ChristopherOkhravi  8 месяцев назад

      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 😊

    • @BlindVirtuoso
      @BlindVirtuoso 8 месяцев назад

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

    • @BlindVirtuoso
      @BlindVirtuoso 8 месяцев назад

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

    • @ChristopherOkhravi
      @ChristopherOkhravi  Месяц назад

      @@BlindVirtuoso Yes, it's available as a PDF on theobjectorientedway.com

  • @AlgoristHQ
    @AlgoristHQ 7 месяцев назад

    I write code in C#. Technically, if I don't override any base class methods or if I don't use base classes, then I can't violate the LSP. I dont find this to be a particularly useful definition..
    In C#, the LSP changes. We talk about implementing interfaces instead of inheriting from super classes.
    All implementations must correctly implement all methods on the base interface. This means that a method can consist of one line throwing an exception.
    Some people say that LSP means that you must use the most abstract class in your code and let DI do the work of populating the correct class. There is no value to doing this ALL of the time.
    Interfaces should only be used when mocking for testing is needed or if you are implementing something like a strategy design pattern. Otherwise, you are increasing the amount of code in your code base for no discernable reason.

    • @ChristopherOkhravi
      @ChristopherOkhravi  7 месяцев назад

      Thank you for sharing your experiences 😊🙏 LSP applies to interface implementation as well and not just inheritance. LSP is fundamentally about subtyping not about inheritance. In this video I use the term “inherits” because this case regards inheritance between interfaces. If you have the time I would highly recommend my videos on LSP (ruclips.net/video/7hXi0N1oWFU/видео.html) and on variance (ruclips.net/video/FdFBYUQCuHQ/видео.html). They help elucidate why LSP applies to subtyping and not just class inheritance. Thanks again for watching and for sharing 😊🙏

  • @bogdanf6698
    @bogdanf6698 8 месяцев назад

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

  • @wilkesreid
    @wilkesreid 8 месяцев назад

    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.

  • @pixaz
    @pixaz 8 месяцев назад

    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  8 месяцев назад +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 8 месяцев назад

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

  • @sharpfang
    @sharpfang 8 месяцев назад

    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.

  • @_akagrawal
    @_akagrawal 3 месяца назад

    Can someone give an example of weaker precondition ?

  • @filippobuonco95
    @filippobuonco95 8 месяцев назад

    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  8 месяцев назад +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 😊🙏

    • @ChristopherOkhravi
      @ChristopherOkhravi  8 месяцев назад +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.

  • @3a146
    @3a146 5 месяцев назад

    Contravariant means Modus Ponens, Covariant means weakening, and the reason why compiler or language type system cannot cover all cases is because of the Rice theorem, where the algorithm, no matter how good, only checks properties stated in must or may for the behaviors of a variable, not the business uniqueness you wished when coding with literals. As I interprets this, OOP assumes states but knows nothing about the real time, hence paradoxes introduced with incorrect continuation formulation.

  • @grossd18
    @grossd18 8 месяцев назад

    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.

  • @PixelSergey
    @PixelSergey 8 месяцев назад

    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?

    • @HaveYouHeardOfManedWolves
      @HaveYouHeardOfManedWolves 7 месяцев назад

      Throwing an exception which doesn't derive from one potentially thrown by the base method can lead to unexpected failure, and simply silently failing to add the value is clearly not ideal, but (while I'm not an expert on the matter) it seems to me like having the base add method return whether or not the item was successfully added (like HashSet in C#) would be the best solution which doesn't require making multiple supertypes, since it communicates that subtypes may refuse to add an item and that callers should expect to handle such cases

    • @Stop_Making_Sense1
      @Stop_Making_Sense1 5 месяцев назад

      Immutable list is legal subtype of a list, because there is clear contract for add() defined in a list that states either you add element and return true OR throw and exception if you can not, basically you should never return false and ignore adding an element. Problem is that nodoby is paying attention to that case and always expecting that add will work. So from LSP stand point, immutable list is ok.

  • @peteralexandre6593
    @peteralexandre6593 8 месяцев назад

    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  8 месяцев назад +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 8 месяцев назад

      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.😊

    • @thebigmacd
      @thebigmacd 8 месяцев назад +1

      ​@@peteralexandre6593 another variant of pronunciation you may hear is "hy-rar-kee", or rarely, "hi-er-ar-kee" (this is the most phonetic)

  • @detaaditya6237
    @detaaditya6237 8 месяцев назад

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

  • @johncerpa3782
    @johncerpa3782 8 месяцев назад

    Great video, thank u

  • @etodemerzel1011
    @etodemerzel1011 8 месяцев назад

    Un gustazo escucharte

  • @TrueBlueTransformations
    @TrueBlueTransformations 8 месяцев назад

    Thank you!

  • @tibrec8
    @tibrec8 8 месяцев назад

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

    • @ChristopherOkhravi
      @ChristopherOkhravi  8 месяцев назад +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 😊

  • @ReviewSutras
    @ReviewSutras 8 месяцев назад

    Can we have examples?

    • @ChristopherOkhravi
      @ChristopherOkhravi  8 месяцев назад +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 8 месяцев назад

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

  • @albertwang5974
    @albertwang5974 8 месяцев назад

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

  • @albertwang5974
    @albertwang5974 8 месяцев назад

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

  • @alejandroioio6784
    @alejandroioio6784 8 месяцев назад

    😎

  • @mortenbork6249
    @mortenbork6249 8 месяцев назад +5

    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.

    • @TuxCommander
      @TuxCommander 8 месяцев назад +1

      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 8 месяцев назад

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

    • @TuxCommander
      @TuxCommander 8 месяцев назад +2

      ​@@mortenbork6249the compiler is not stopping you from throwing a NotImplementedException, in an Interface implementation.
      Contract fulfilled, LSP broken.
      That simple.

    • @mortenbork6249
      @mortenbork6249 8 месяцев назад

      ​​@@TuxCommander
      You simply haven't understood what composition means.
      There is no sub type. There are only other implementations of an interface.
      Not implemented exception is then the precise desired behaviour of your implementation.
      LSP requires! A comparison class.
      Another implementation of an interface is not an inherited sub class. Both implementations are super classes.
      That share a contract. You simply misunderstood what composition is.

    • @mortenbork6249
      @mortenbork6249 8 месяцев назад

      ​@@Robert-yw5msplease see my answer to tu. Why your argument isn't valid. You both have the same issue.

  • @ajzack983
    @ajzack983 8 месяцев назад +1

    Liberal is weaker, conservative is stronger.
    Got it.

    • @thebigmacd
      @thebigmacd 8 месяцев назад

      I feel like "broader" and "narrower" would be more descriptive of the range of accepted values than "weaker" and "stronger", respectively.

  • @RobertShresthawolf
    @RobertShresthawolf 8 месяцев назад +1

    First one here :)

  • @greob
    @greob 8 месяцев назад +1

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