4. Liskov Substitution Principle (LSP) Flashcards
How does LSP-compliant code relate to the OCP?
Liskov Substitution Principle tends to produce code that better follows the Open/Closed Principle.
What does the LSP state?
Subtypes must be substitutable for their base types.
What does basic object-oriented design teach to think about objects and their relationships with one another?
Using two characteristics — inheritance (IS A) and properties (HAS A).
Inheritance: An eagle IS A bird.
Property: An address HAS A city.
How does LSP differ from the teaching of basic object-oriented design?
LSP states that the IS A (inheritance) relationship is insufficient and should be replaced with IS SUBSTITUTABLE FOR.
How does the relationship between a rectangle and a square relate to LSP?
Square has an invariant (its sides must be equal) that clashes with the rectangle’s invariant (its sides are independent). Therefore, a square is not substitutable for a rectangle because the code that works with a rectangle might expect to set different lengths for the width and the height of the rectangle.
This design violates LSP.
What are the three common symptoms that LSP might be being violated in real-world code?
- Type checking with
is
oras
in polymorphic code, since polymorphism implies substitution. - Null checks — often looks quite similar to type checks.
- NotImplementedException — pretty much every time you see this exception, it’s an indication that an interface or base class was only partially supported, and some of its features were left unimplemented. By definition, this type cannot be substitutable for its interface or base class for all places it might be called.
What can be said about null
s in regards to the LSP?
That they’re not substitutable for actual instances and therefore violate the Liskov Substitution Principle.
What is the relationship between LSP and polymorphism?
Liskov Substitution principle is a subset of polymorphism — all types that follow LSP also support polymorphism. More importantly, anywhere that you want to use polymorphism, you almost certainly want substitutability (LSP).
What is the “Tell, Don’t Ask” principle?
DON’T ASK instances for their type and then conditionally perform different actions, but instead, encapsulate that logic in the type itself and TELL it to perform an action.
How can we minimize null checks in C#?
- C# features — nullable reference types, null conditional operators, null coalescing operators.
- Guard clauses — prevent null values from reaching the primary logic in your methods.
- Null Object design pattern — provides a useful way to prevent null checks and provide an LSP-compliant instance to use when you might otherwise have used a null.
How can we fix LSP violations?
- Follow the “Tell, Don’t Ask” principle.
- Minimize null checks
- Whenever you implement an interface or inherit from a base class, make sure you fully implement it (Interface Segregation Principle).
What are the key takeaways of this module?
- Subtypes must be substitutable for their base types.
- Ensure base type invariants are enforced.
- Look for type checking, null checking, and NotImplementedException