- Published on
 - View count
 - 236 views
 
Liskov Substitution Principle (LSP)
- Authors
 
- Name
 - Francisco Moretti
 - @franmoretti_
 
Usage
📝 Guideline
Liskov Substitution Principle: Child classes should be able to replace parent classes without causing errors or unexpected behavior.
The Liskov Substitution Principle states that if S is a subtype of T, then objects of type T may be replaced with objects of type S. In simpler terms, if you have a parent class and a child class, you should be able to use the child class wherever the base class is expected without encountering incorrect results.
🛠️ How to Apply
- Use inheritance correctly: Make sure that subclasses can be used interchangeably with their base classes without causing unexpected behavior or violating the base class's contract. 🔄
 - Adhere to method signatures: Child classes should maintain the same method signatures as their base classes to ensure that they can be used as substitutes without introducing errors. 🖋️
 - Avoid violating preconditions: Subclasses should not impose more restrictions on input parameters than their base classes. Strive to relax or maintain the same preconditions as the base class methods. 🔓
 - Preserve postconditions: Ensure that the postconditions defined by the base class methods are still valid in the subclass implementations. The output and behavior should remain consistent. ✅
 
Pros and Cons
👍 Pros
- Enhances code reusability: The Liskov Substitution Principle allows for easy interchangeability of objects, promoting code reuse and modularity. 🔄
 - Facilitates abstraction: LSP encourages the creation of well-defined base classes and contracts, which promote clear and concise abstractions throughout the codebase. 💡
 
👎 Cons
- Increased complexity: Designing and maintaining a hierarchy of classes that adhere to the Liskov Substitution Principle may introduce additional complexity, especially in larger codebases. 🤯
 - Requires careful design: Applying LSP effectively requires thoughtful design and planning to create a hierarchy that allows for substitutability without breaking the system's behavior. 🎨
 
Examples
❌ Bad
class Bird {
  fly() {}
}
 
class Duck extends Bird {} // Ducks can fly
 
class Ostrich extends Bird {} // Ostriches also have a `fly` method, but ostriches can't fly.✅ Good
class Bird {}
 
class FlyingBirds extends Bird {
  fly() {}
}
 
class Duck extends FlyingBirds {} // Ducks can fly
 
class Ostrich extends Bird {} // Ostrich can't fly, but they are still birdsReferences
🧱 SOLID Principles
SOLID is an acronym for five other class-design principles:
- Single Responsibility Principle (SRP)
 - Open-Closed Principle (OCP)
 - Liskov Substitution Principle (LSP)
 - Interface Segregation Principle (ISP)
 - Dependency Inversion Principle (DIP)
 
🔀 Related principles
- Single Responsibility Principle: Each class or module should have only one reason to change, promoting cohesion and reducing the likelihood of violating the Liskov Substitution Principle. 🎯
 - Open/Closed Principle: The Liskov Substitution Principle is closely related to the Open/Closed Principle, as both aim to promote extensibility and modifiability of code. 🚪
 - Interface Segregation Principle: By adhering to the Interface Segregation Principle, clients are only dependent on the specific interfaces they require, which can help ensure conformance to the Liskov Substitution Principle. 🧩
 - Dependency Inversion Principle: The Dependency Inversion Principle encourages the use of abstractions and dependency injection, which can facilitate adherence to the Liskov Substitution Principle. 🔄
 - Composition Over Inheritance: Instead of relying heavily on inheritance, the Composition Over Inheritance principle suggests using composition and interfaces to achieve flexibility and prevent Liskov Substitution Principle violations. 🧱
 - Law of Demeter (Principle of Least Knowledge): By following the Law of Demeter, objects should only interact with their immediate dependencies, reducing the chances of Liskov Substitution Principle violations. 📞
 - Keep it short and simple (KISS): Keeping code simple and straightforward can aid in adhering to the Liskov Substitution Principle and avoiding unnecessary complexities. 🤐
 - YAGNI principle: The YAGNI principle discourages adding functionality prematurely, which can help maintain the integrity of the Liskov Substitution Principle by not introducing unnecessary complexity. ❌
 - Principle of Least Astonishment: This principle suggests designing code in a way that minimizes surprises and aligns with users' expectations, indirectly supporting adherence to the Liskov Substitution Principle. 😮
 - Inversion of Control (IoC): By applying IoC, the control flow of a program is inverted, allowing for easier substitution of components and facilitating adherence to the Liskov Substitution Principle. ⬆️
 - Law of Superposition: The Law of Superposition in software design suggests that more specific behaviors should not override or conflict with more general behaviors, aligning with the Liskov Substitution Principle. 🌟
 - Design by Contract: Design by Contract emphasizes the use of preconditions, postconditions, and invariants to ensure the correct behavior and adherence to contracts, which can support the Liskov Substitution Principle. 📝