4 ms·
I have always felt that people use OO exactly the opposite as Liskov suggests. Liskov says that subclasses must be fully substitutable, and that implies that a
by jrockway 6y ago
I have always felt that people use OO exactly the opposite as Liskov suggests. Liskov says that subclasses must be fully substitutable, and that implies that any valid operation on the superclass must be valid on the subclass. So say you have a Bag class. You can add elements to it at will. Then you create a Set subclass, and now inserting a duplicate throws an exception. You just broke substitutability. Even though the code is easy express with this hierarchy (if exists(element) throw else super(element)), your program blows up if you try to substitute. Doing the opposite is safe, of course, but the code reuse doesn't work when you make your Bag a subtype of Set. From an algorithm standpoint, a Bag isn't really implemented in terms of a Set, so you're writing a new data structure from scratch (rather than just changing one condition in insert() like the invalid example).
What I take away from this is that people are mostly using OOP to cut-n-paste code when two things are similar. I see the value in not wanting to rewrite code (or to create a third "common factor" that you will never use, to implement Set and Bag), but I think this use of OOP basically precludes any computer science reasoning when looking at your classes. Apparently that's not a problem, as people are ignoring Liskov right and left while building good stuff. But thinking about it deeper, I fear that we didn't find the right model when we invented OOP, and that is why newer languages are ignoring OOP in favor of composition.
- narag 6y agoFor some people, programming languages are much like math, so there's right and wrong, and there's a right way to do OOP, or even OOP is or isn't right in itself. Maybe I'm wrong, but I tend to see language features as a usability question. In different human languages (or even in the same language) you can say the same thing using different syntax, but one way of saying it is more clear or more inspiring. It's not what some object is, it's how it works better what makes sense to me. Again, that's just me, YMMV.
- mumblemumble 6y agoI agree, it's better to be pragmatic. So it's not super useful to say that LSP is about whether you're doing it right or wrong. I prefer to think of it in terms of making the codebase intuitive to work in. So I like to formulate it as, "You should be able to safely and fearlessly plug any subtype of a class into a method that accepts that class as an argument." This is a bit of a departure from how Liskov originally formulated things, but I think it is fair to say that it's a refinement that better captures the spirit of how she talks about it in more recent interviews. And it also captures why it's such an important principle, especially if you're working on a team: Nobody wants to get stuck working in a codebase where Widgets are partitioned into two different categories that can only be distinguished by carefully reading their implementations, according to criteria that can only be understood by carefully reading the implementations of methods that operate on Widgets. It's not wrong, per se, it's just not a working environment that any self-respecting person wants to be stuck in..
- tcgv 6y agoTo correctly apply the LSP when designing subclasses it's not enough to just ensure syntactic safety but also behavioral correctness. The Bag example you gave is an example of not ensuring behavioral correctness. > Doing the opposite is safe, of course, but the code reuse doesn't work when you make your Bag a subtype of Set I disagree. suppose the Bag class only allows unique entries, then if you create a subclass that overrides this behavior to allow duplicates you are breaking an expectation the system may have about Bags, and possibly relies on, provoking unexpected consequences. For instance, allowing duplicates in Bags may trickle down to an inventory shortage issue since the system plans at most one item of each type per user.
- voxl 6y agoThere is nothing wrong with Set being a subtype of Bag, the problem is that the type system you're discussing doesn't enforce it. If a Set were merely a Bag that must statically enforce the constraint that all elements are unique then there wouldn't be any issues.
- deleted 6y ago[deleted]