Grokking SOLID Design Principles
Ask Author
Back to course home

0% completed

Vote For New Content
Break The Hierarchy for Adhering to LSP
Table of Contents

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

In the previous lesson, we identified the problem where the ElectricCar class violated the Liskov Substitution Principle by failing to implement the refuel() method properly. Now, we will redesign the inheritance hierarchy to follow LSP by introducing a generalized Vehicle class.

Step 1: Create a General Vehicle Class

We’ll begin by creating a generalized Vehicle class, which defines common behaviors shared by all vehicles, such as starting and stopping, and an abstract refuel() method for specific fuel/energy behavior.

Python3
Python3
. . . .

The Vehicle class provides basic vehicle functionality, with refuel() left abstract for subclasses to implement according to their specific fuel or energy requirements.

Step 2: Refactor Car and ElectricCar Classes

Car Class (Inherits from Vehicle)

Python3
Python3
. . . .

The Car class inherits from Vehicle and implements the refuel() method specific to gasoline-powered cars.

ElectricCar Class (Inherits from Vehicle)

In the ElectricCar class, we will introduce a recharge() method for charging the electric car's battery, and we will call this method from the overridden refuel() method.

Python3
Python3
. . . .

Here, the refuel() method in ElectricCar calls the recharge() method, which reflects the real-world behavior of electric cars needing to recharge their batteries instead of refueling with gasoline.

Step 3: Test the New Hierarchy

Let’s test the system by creating instances of both Car and ElectricCar and see how they behave.

Python3
Python3

. . . .

How This Solution Follows LSP?

With this new design:

  • Both Car and ElectricCar inherit from Vehicle, and they can be used interchangeably without breaking the program.
  • Each subclass (Car and ElectricCar) implements its own version of the refuel() method. For the electric car, refuel() calls the specific recharge() method, maintaining expected behavior without breaking the contract of the Vehicle class.
  • This ensures that the Liskov Substitution Principle is followed: an instance of ElectricCar can replace Car without causing issues.

When to Break the Hierarchy

  • When Subclasses Can’t Implement Parent’s Behavior: If a subclass can’t fully follow the parent’s contract (e.g., ElectricCar refueling), it’s time to rethink the hierarchy.

  • When Subclasses Behave Too Differently: If subclasses have vastly different behaviors, a more general parent class may be needed to avoid forcing inappropriate methods on subclasses.

  • When Conditionals Increase: If you're adding too many conditionals in subclasses, it's a sign that the hierarchy isn’t flexible enough and needs refactoring.

Breaking the hierarchy is useful when you notice these patterns, helping you build more flexible and maintainable systems.

.....

.....

.....

Like the course? Get enrolled and start learning!

Table of Contents

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible