The Liskov Substitution Principle (LSP)

In 1988, Barbara Liskov wrote this principle in the following way as a way to identify subtypes:

What is wanted here is something like the following substitution property: if for each object o1 of type S there is an object o2 of type T so that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T.

And it is paraphrased as the following by Robert C. Martin in his book, Agile Software Development: Principles, Patterns, and Practices:

Subtypes must be substitutable for their base types.

Here, we're going to use the square/rectangle problem from Agile Software Development: Principles, Patterns, and Practices, as an example of a violation of LSP, since we know that, logically, a square is a rectangle. As shown in the following diagram, the Square class inherits from the Rectangle class. Usually, the inheritance is regarded as the IS-A relationship. The App class depends on the Rectangle class:

Figure 6.1: Rectangle and Square

As you can see, the Rectangle class has two fields and their setters and getters, as well as the calculateArea() method. In the Square class, the setWidth() and setHeight() methods override the setters in its base class.

The following is the code of the Square class and the App class. For the sake of brevity, the Rectangle class is not shown here:

public class Square extends Rectangle {
public void setWidth(int width) {
this.width = width;
this.height = width;
}
public void setHeight(int height) {
this.height = height;
this.width = height;
}
}

public class App {
public void resize(Rectangle rectangle) {
rectangle.setWidth(10);
rectangle.setHeight(5);
int area = rectangle.calculateArea();
assert area == 50;
}
}

As you can see in the setWidth() and setHeight() methods of the Square class, we keep the width and height the same value, which makes perfect sense.

So, what is the problem with this design? The problem is that inside the resize() method of the App class, when we call this method with an object of Square, the assertion will be false. After rectangle.setHeight(5), inside that object, both the width and height will be at a value of 5. The value of area will be 25 instead of 50. However, the assertion will be true when the parameter we pass in is an object of Rectangle.

This is a violation of the LSP. The Square subtype cannot substitute its base type, Rectangle, in the resize() method. So, why this is a problem? Because, from the perspective of the App class, Rectangle and all its subtypes should behave the same.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.75.70