Episode 11 – Liskov Substitution Principle

Clean Code

Episode 11

This episode talks about the principle govern inheritance, polymorphism and subtyping.

Part 1:

  • Type Theory
    • “This statement is false” is a paradox.
  • Types
    • Solution is typing to avoid paradox loop.
  • What is a Type?
    • A Type is a bag of operations and how the data is stored is not matter to us as long as the operation is done correctly.
    • Similar to a class, a class is nothing but its methods and the data is hidden as private.
  • Subtypes
    • A subtype relationship of described point as a subtype of point is when described point can be cast into point but not visa versa.
  • Liskov & subtypes
    • What is wanted here is something like the following substitution property: If for each object 01 of type of S there an object 02 of type T such that for all programs P defined in term of T, the behavior of P is unchanged when 01 is substituted for 02 then S is a subtype of T.
  • Duck typing
    • Invoking method vs Send Message (Static vs dynamic language)
  • Refused Bequest
    • Refused Bequest is when an object invoke a method or send a message that is not expected.
    • Exception and side effect by the subtype that the base type didn’t expect
  • The Representative Rule
    • Rectangle and subtype Square with setHeight and setWidth vs setSide
  • Refused Bequest!
    • When program setHeight on an object of square, there is an undefined behavior of how to handle a setHeight in a square.
  • Latent OCP Violation
    • Dependency will be created when fixing the problem by checking if a Rectangle is a Square in the program. This is a violation of Open Close Principle.
  • Solution
    • Treat square and rectangle completely different type.
  • The Representative Rule
    • Representative does not share the same relationship of the objects that they represent
  • Number
    • Integer is subtype of Real and Real is subtype of Complex
    • However, complex number has two parts of Real number, one for the real value, and the other for the imaginary.
    • In programming, this complex and real relationship will create a recursive definition similar to the paradox at the beginning of the episode.
    • This is an example where real world model does not work with a computer representation
  • Lists
    • If S is subtype of T, List of S is not a subtype of List of T
    • For example, a Circle is a subtype of Shape but List of Circle is not a subtype of List of Shape because a List of Shape could include Rectangle, Square and other Shapes.

Part 2:

  • Heuristics
    • If base class does something, the derived class must do it too in a way that does not violate the expectation of the caller. This is appearance when a derived class throw an unconditional exception for a method or override with an empty method that the base class implemented.
    • Another indicator is the usage of if instanceof is being used.
    • Only use instanceof when you know the type to help the complier.
  • Typecases
    • The use of if instanceof can lead to additional else if instanceof and should replace with polymorphic dispatch.
  • Statics vs Dynamics
    • Dynamics language use TDD to help with type checking
  • Design by Contract
    • invariant, precondition and postcondition.
  • The Modem Problem
  • Long Distance Rigidity
  • Adapter
    • Adapter is derive from the Modem and delegate to the Ded Modem in the example.
    • If you need an ugly hack, make sure to isolate it from the system by pointing all the dependency away from it.
  • Conclusion
  • References
    • The Annotated Turing by Charles Petzold
    • Advanced C++ Programming Style and Idiom by James Coplien
    • Refactoring: Improving the design of existing code by Martin Fowler
    • Object-oriented Software Construction by Bertrand Meyer