Liskov Substitution Principle

In this Object Oriented world, learning SOLID principles had become one of the most interesting thing. Today’s topic is somewhat related to SOLID.

If you are new to SOLID, then SOLID is an object oriented principle which will guarantee that our software module won’t break with change requirement of a software.
Confused!!! Let’s make it easy. You can say that, “Software systems built by applying SOLID principles are easy to maintain and extend over time”.

I am a trainer. I do corporate training in many organizations. Recently I have done one training on Design pattern in Step by Step Schools. Step by Step schools is an offline technical institute owned by me located at Mumbai. As a part of this training I was discussing about SOLID patterns with my students. It went well with following topics.

  • What is SOLID?
  • Understand S – Single Responsibility principle in SOLID
  • Understand O – Open Closed principle in SOLID

Then I started L – Liskov substitution principle. I started with the definition of this principle.

It says “Subclasses should be substitutable for base classes”.

By hearing such definition all my students got astonished.

Liskov

They said, “This principle just doesn’t make sense at all.”

Actually they were correct somewhat. As per the object oriented programming rule we can always right following syntax.

Base b=new Derived ();

We can always have a function like below.

public void SomeFunction(Base b){....}

Which can be invoked as below.

SomeFunction(new Derived1());
or
SomeFunction(new Derived2());

//Note: Its assumed that Derived1 and Derived2 are 2 derived classes of class called Base.

It means, “We can always use child class instance where base class is expected.”

But in really above statement is not true. Let me give you a simple and realistic example.
Assume that we have a project with a database having table Customer with three columns – Name, Address and Age. In that case we ultimately end up with following class in our code.

public class Customer
{
public string Name{get;set;}
public string Address{get;set;}
public int Age{get;set;}
}

Now let’s say we have one more table in Database called Employee with columns – Name,Address and Age.
Object oriented programming is full of useful and worth to follow principles. One of the the useful and worthwhile principle is DRY – Don’t repeat yourself. It says “Once a particular code is written, don’t write it again simply reuse it”. From a newbie to experienced, everybody respects this principle and try their best to follow it.
By keeping DRY in mind and considering existing Customer class, new Employee class can be created as follow.

public class Employee:Customer{}

Technically above statement seems correct but logically it’s incorrect. Above inheritance relationship states that “Every customer is an Employee”, which is not actually not true all the time.

We cannot actually use Customer where it’s expecting to have employee. This is where we say “we designed our system in a way, where every derived class is not a substitutable for base class” or more simply we say “we are violating Liskov substitutional principle”.

What’s the proper design then?

After hearing all this explanation one of student quickly asked, “Sir, what is the correct design then ?”
Well, considering both DRY and LSP is followed our classes can be designed as follows.

public class Person{
	property string Name{get;set;}
	propertystring Address{get;set;}
	property int Age{get;set;}
}
public class Employee:Person{
	//Additional properties
}
public class Customer:Person{
//Additional properties
}

Any code which expects person will work with both Employee and Customer.

So that’s the one of my “Step of the step” story. Hope you enjoyed the post. Please post comments, Share the link in your FB, twitter, linked in etc. Stay tuned, I will be soon back with one more new story.

Comments

comments

Leave a Reply