Thursday 16 February 2017

Liskov’s Substitution Principle - A SOLID principle


Derived types must be completely substitutable for their base types.

Explanation:
To utilize the principles like inheritance, we create some class hierarchies (=extends some classes creating some derived classes).

LSP states that if a program module is using a Base class, then the reference to the Base class can be replaced with a Derived class without affecting the functionality of the program module i.e. we must make sure that the new derived classes just extend without replacing the functionality of old classes.

Otherwise the new classes can produce undesired effects when they are used in existing program modules.

package core.solid;
/**
 * Violation of Liskov's Substitution Principle
 */
class Rectangle {
     protected int width;
     protected int height;

     public void setWidth(int width){
           this.width = width;
     }

     public void setHeight(int height){
           this.height = height;
     }

     public int getWidth(){
           return width;
     }

     public int getHeight(){
           return height;
     }

     public int getArea(){
           return width * height;
     }   
}

class Square extends Rectangle {

     public void setWidth(int width){
           this.width = width;
           this.height = width;
     }

     public void setHeight(int height){
           this.width = height;
           this.height = height;
     }
}

public class LSPTest {

     private static Rectangle getNewRectangle() {
           /**
            * It can be an object returned by some factory.
            */
           return new Square();
     }

     public static void main (String args[]) {
          
           Rectangle rObj = LSPTest.getNewRectangle();

           /**
            * User knows that rObj it's a rectangle.
            * It assumes that he's able to set the width
            * and height as for the base class
            *
            * But the height and width are setter has
            * been changed as per the SQUARE property.
            **
            */
           rObj.setWidth(5);
           rObj.setHeight(10);

          
           /**
            * Unexpected result as the area of SQUARE calculated but
            * he was expecting the area of rectangle.
            **/
           System.out.println(rObj.getArea());
     }
}

Rectangle and Square two classes are used in the Application. We extend the application and add the Square class. The square class is returned using a factory pattern, based on some conditions and we don't know the exact what type of object will be returned. But we know it's a Rectangle.

We get the rectangle object, set the width to 5 and height to 10 and get the area. For a rectangle with width 5 and height 10 the area should be 50. Instead the result will be 100(=because rectangle class is Substituted by the Square class).

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...