SOLID: Liskov Substitution Principle

It is time for the third entry for the SOLID series, after the SRP and the OCP, I’ll introduce the Liskov Substitution Principle (LSP). This concept has been introduced by Barbara Liskov in 1984, with Jeannette Wing they define this principle as the following:

Let q(x) be a property provable about objects x of type T. Then q(y) should be provable for objects y of type S, where S is a subtype of T.

Well, if you are like me you must be still trying to figure this one out to understand how it can be applied to Object Oriented Programming. Do not worry, a more accessible rule has been defined to specify the LSP.

Subtypes must be substitutable for their base types.

In other words it means that consuming any implementation of a base class should not change the correctness of the system. To give more depth to this principle I will use the famous Rectangle-Square example to show how this rule can be violated.

Let me resume the situation: I have a rectangle of 10 by 5 and its area is 25?! This does not make sense. Even if the inheritance seems legitimate, the way it is used in my application violates the Liskov Substitution Principle.

Using the NotSupportedException of the .NET framework is likely showing that the LSP is not respected in your source code. There is even a part of this same framework that transgress this principle.

The ReadOnlyCollection does not allow any modification to the collection, it is impossible to add or remove items in it. Yet its the ICollection interface that defines methods to manipulate the items: the LSP is clearly violated.

The LSP is closely related to the Design by Contract approach to create software. This way your thinking ahead of the pre-conditions, post-conditions and side effects for your application and every implementations of your subtypes are related to your contracts.

This is the end of the introduction to the Liskov Substitution Principle and especially how to detect when the rule is broken. I am still working on a relevant example to demonstrate how to start from a “bad” code sample, like the ones I gave you, to a sample that respect the LSP.

In the meantime do not hesitate to give your opinion regarding this topic.

3 thoughts on “SOLID: Liskov Substitution Principle”

Interesting problem. Overriding the setters to also set the other attribute looks only like a solution if you completely ignore that code should not be surprising, but setting length on a rectangle and getting the same width would probably be surprising. So what would be a good solution…

Hi Twisted Inspiration,
Thank you for sharing your thoughts on this topic.
In my opinion, to fix the Square-Rectangle problem, the thing to do is to remove the inheritance between the 2 classes. Both should inherits an interface IShape (for instance) that only provides a CalculateArea() method. Or the setters for Width and Height should not be available and these 2 values are actually set only with the constructor.
There are several options available it depends on the context of your application and on what you want to do with the Square and the Rectangle.
I hope this can help you understanding the Liskov Substitution Principle.