Wednesday, March 27, 2013

L is for...

L is for Liskov Substitution Principle

This principle essentially states that for a class N and a subclass of N called O then O can be substituted for N without breaking the program. Following this principle can help a program respect the Open/Closed principle. For this post, I have two examples. One where I successfully followed this principle and another where I fell into a classic trap.

Let's start with success. This example is again my responders in my http server. All of the responders implement a responder interface. Because they all do this, they are each interchangeable with the responder interface. Java confirms this by letting me use the interface as a function argument and not exploding when I instead pass in a specific responder.

This does not mean that all I had to do to follow this principle was to implement an interface. I had sorta violated it during a small presentation I gave on code smells, though I didn't know it at the time. During that presentation, I said that a square and a rectangle shared enough class data to be derived from a common class. After all, a square is a rectangle, right?

Without knowing it, probably because I hadn't read PPP yet, I had fallen into a classic trap. Mathematically a square is a rectangle but not in terms of setting attributes on a class. A square really only has one attribute, so updating the width also updates the height. On a rectangle, those two attributes can be updated independently.

The problem comes when I want to pass a square into a function that takes a rectangle. What should I expect setting the height to do? If it were a rectangle, then setting the height would not change the width. For a square, changing one changes the other. The confusion here is evidence that the proposed relationship between a square and a rectangle violates the Liskov Substitution Principle. Let's hope I can avoid that mistake in the future.

No comments:

Post a Comment