Liskov Substitution Principle is the L in the SOLID programming principles. It was announced to the world by Barbara Liskov in a 1987 conference keynote address titled Data abstraction and hierarchy.
In that academic setting, using academic linguo, Liskov stated that in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S – meaning that any object of type T can be easily substituted with any object of subtype S) – without altering any of the desirable properties of T (without bugs & errors while achieving the same result).
In layman terms, what it states is that if you create a concise and well defined abstract Object, and then you define another more specific Object based on the first one, you can only know you’ve done it right if, and only if, the second Object can be substituted for the first.
So why is it useful. Well, you knowingly (or unknowingly) abide by this principle when creating good SOLID Class hierarchies.
Say for example that you have a Car Object and a Truck Object. You explicitly state their specific behavior and declare what makes a Car a car and a Truck a truck. After you write them up, being the perceptive and earnest programmer that you are, you notice that both these object share some behavior. Namely some methods are close to identical between classes.
Both Car and Truck have start_engine, both have drive, and both have steer. In a well appreciated effort to DRY up your code you decide to take the common functionality and place it all in one place. You think of a Vehicle Object and place all common behavior between Car and Truck in the newly Defined Vehicle Class.
Then all that’s left for you to do is inherit this common – and still very important functionality – from the Vehicle class like so:
class Car < Vehicle #... end class Truck < Vehicle #... end
If this sounds familiar to you then you might be thinking “Hey, that’s classical inheritance”. And you’d be absolutely right.
You see , Liskov’s Substitution principle is not a novel idea. It’s not something that didn’t exist before it was put on paper and made public. What Barbara Liskov did was analyze good coding practices and compared them with bad coding practices. Slowly a pattern emerged, and it did so because she came down from the top, analyzed the end result or goal of each program or application and then factored in the cost (developer man hours, coding difficulty, maintainability, changeability etc). She extracted the commonality or pattern shared by successful coding practices, boiled them down until she could define the abstraction and slapped a name on it.
If this sounds like an oversimplification of things then you’d be right. But I do not mean to belittle Liskov’s work. It holds as much importance today as it did back in 1987 – if not more.
Now, the example given is an obvious case of applied classical inheritance. This is so because in the example given the Car and Truck Objects are central to the main scope or business logic of the application. That being said, defining separate and more specific Objects and having them inherit from an abstract Object, namely the Vehicle Class, that shares all the common behavior, is a given.
But like all good and proper programming principles & paradigms, Liskov’s Substitution Principle is a guide-line and not a rule set in stone. This means that there are not “cut outs” or shortcuts that state: “hey, when faced with this scenario or problem, apply this principle or solution”.
Case in point, in other more specific parts of your application, you might be dealing with the same commonality amongst objects and the best course of action would be to Duck Type.
If you are unfamiliar with the practice, in layman terms it just states that “if it looks like a duck and it walks like a duck, then it must be a duck”. In programming linguo this translates to:
“If this specific object looks like those specific Objects, and it behaves like those specific Objects, then it must be the same type”. But more about Duck Typing and what you need to easily and efficiently amass Duck Types in a later post.