Does the fact that there are Stream derived classes that cannot be written or sought break the Liskov substitution principle?
For example, the NetworkStream cannot b
CanSeek
technically keeps the stream classes from violating LSP. Only if it returns true, does seeking promise to work.
I personally consider it a severe bending of ISP and possibly SRP, and my inner designer would have preferred something like a SeekableStream
subclass/interface that seekable streams could inherit from. But i'm sure that brings problems of its own (for instance, in streams that are only sometimes seekable)...and frankly, real-world usability trumps principle.
That is something to keep in mind. Once in a while, principle and reality collide. SOLID principles help minimize unneeded complexity in most cases, and generally keep OO systems maintainable and prevent them from collapsing under their own weight. If purity results in a system that's more complex, though -- for instance, because now an only-sometimes-seekable stream doesn't fit well into the hierarchy -- then perhaps an occasional bit of ugliness is justifiable.
But it should never be the first choice just because the letter of the law allows it. SOLID principles aren't just rules; they're principles. They're the ideas behind the words -- the spirit of the law. If you stick to the letter while lawyering your way past the spirit, you're missing the whole point of the principle.
As for the Square/Rectangle problem...technically, having properties/functions that determine whether changing the height will change the width as well, could be considered in keeping with the letter of LSP. Again, though, it feels like lawyering, and is pushing the bounds of other SOLID principles. It's also definitely not an optimal solution from reality's perspective, as it increases complexity and introduces the possibility for accidental side effects; now everything that wants to say rect.Height = 50;
can unintentionally change the width as well.