Liskov Substitution Principle (LSP)
In this tutorial, we are going to discuss Liskov Substitution Principle (LSP) in SOLID Principles. Liskov Substitution Principle is a variation of previously discussed open closed principle.
Barbara Liskov introduced the principle in 1987, and according to this principle, “Derived or child classes must be substitutable for their base or parent classes“.
In other words, if class X is a subtype of class Y, then we should be able to replace Y with X without interrupting the behaviour of the program.
You can understand it in a way that a farmer’s son should inherit farming skills from his father and should be able to replace his father if needed. If the son wants to become a farmer, he can replace his father, but if he wants to become a cricketer, the son definitely can’t replace his father even though they both belong to the same family hierarchy.
This principle is a bit tricky and interesting all it is designed based on Inheritance concepts, so let’s better understand this with an example
Let’s consider I have an abstract class called SocialMedia, which supported all social media activity for the user to entertain them like below
package com.ashok.solid.principles.lsp;
/**
*
* @author ashok.mariyala
*
*/
public interface SocialMedia {
public abstract void chatWithFriend();
public abstract void publishPost(Object post);
public abstract void sendPhotosAndVideos();
public abstract void groupVideoCall(String... users);
}
package com.ashok.solid.principles.lsp;
/**
*
* @author ashok.mariyala
*
*/
public class Facebook implements SocialMedia {
@Override
public void chatWithFriend() {
// logic
}
@Override
public void publishPost(Object post) {
// logic
}
@Override
public void sendPhotosAndVideos() {
// logic
}
@Override
public void groupVideoCall(String... users) {
// logic
}
}
In the 20th century, I believed everyone using this Facebook APP, and all the features mentioned above are available on Facebook. So that we can consider Facebook as a complete substitute for SocialMedia class, both can be replaced without any interruption.
Now let’s discuss WhatsApp class
package com.ashok.solid.principles.lsp;
/**
*
* @author ashok.mariyala
*
*/
public class WhatsApp implements SocialMedia {
@Override
public void chatWithFriend() {
// logic
}
@Override
public void publishPost(Object post) {
// Not Applicable
}
@Override
public void sendPhotosAndVideos() {
// logic
}
@Override
public void groupVideoCall(String... users) {
// logic
}
}
Here, due to the publishPost() method, WhatsApp child is not a substitute for parents SocialMedia because whatsapp doesn’t support uploading photos and videos for a friend. It’s just a chatting application, so it doesn’t follow LSP.
Now let’s discuss Instagram class
package com.ashok.solid.principles.lsp;
/**
*
* @author ashok.mariyala
*
*/
public class Instagram implements SocialMedia {
@Override
public void chatWithFriend() {
// logic
}
@Override
public void publishPost(Object post) {
// logic
}
@Override
public void sendPhotosAndVideos() {
// logic
}
@Override
public void groupVideoCall(String... users) {
// Not Applicable
}
}
Similarly, Instagram doesn’t support groupVideoCall() feature, so we say Instagram child is not a substitute of parents SocialMedia.
How to overcome this issue so that my code can follow LSP
package com.ashok.solid.principles.lsp;
/**
*
* @author ashok.mariyala
*
*/
public interface SocialMedia {
public abstract void chatWithFriend();
public abstract void sendPhotosAndVideos();
}
package com.ashok.solid.principles.lsp;
/**
*
* @author ashok.mariyala
*
*/
public interface SocialPostAndMediaManager {
public void publishPost(Object post);
}
package com.ashok.solid.principles.lsp;
/**
*
* @author ashok.mariyala
*
*/
public interface VideoCallManager {
public void groupVideoCall(String... users);
}
Now, if you observe, we segregate specific functionality to separate classes to follow LSP.
Now it’s up to implementation class decision to support features, based on their desired feature they can use respective interface for example, Instagram doesn’t support video call feature so Instagram implementation can be designed something like this
package com.ashok.solid.principles.lsp;
/**
*
* @author ashok.mariyala
*
*/
public class Instagram implements SocialMedia,SocialPostAndMediaManager {
@Override
public void chatWithFriend() {
// logic
}
@Override
public void publishPost(Object post) {
// logic
}
@Override
public void sendPhotosAndVideos() {
// logic
}
}
Similarly, WhatsApp doesn’t support publish post feature so WhatsApp implementation can be designed something like this
package com.ashok.solid.principles.lsp;
/**
*
* @author ashok.mariyala
*
*/
public class WhatsApp implements SocialMedia, VideoCallManager {
@Override
public void chatWithFriend() {
// logic
}
@Override
public void sendPhotosAndVideos() {
// logic
}
@Override
public void groupVideoCall(String... users) {
// logic
}
}
This is how you can design Liskov Substitution Principle (LSP).