SOLID Principles — Part3
Build SOLID foundation for your software; write code using SOLID principles.
Liskov Substitution Principle:
- LSP recommends that any function working with a class should also work with subtypes(derived classes) of the class.
- This is more of behaviour related principle. Basically, as a programmer one should be mindful while creating the inheritance hierarchies in a way that the expected behaviour of the function remains intact regardless of usage of class or its subclasses.
- LSP is also know as ‘Design by Contract’
- Ensure the similar behaviour aspect using Pre-conditions and Post-conditions changes.
- With the LSP, a derived class may neither define pre-conditions that are stronger than those of its parent, nor define post-conditions that are weaker than those of its parent class.
- Strategy pattern adheres to LSP and hence easy to correlate by looking at bigger picture.
- Having right abstraction in place can be helpful to adhere to LSP.
Design following the LSP:
Create a protocol called ‘Offer’ and it contains method ‘getDiscountedPrice’.
- For any food delivery or grocery application, we often have requirements to have different types of offers within application. If we create a subclass(ConcreteTypes here) such as ‘DefaultOffer’, ‘OfferOfTheDay’, ‘SpecialOffer’, ‘ABCBankOffer’, ‘XYZWalletOffer’, or ‘Flat50’, then all of these should be able to implement ‘getDiscountedPrice’ to adhere to LSP and return respective offer amount.
- During checkout process, we have the method to calculate total amount with parameter of type ‘Offer’. At runtime, there could be any instance of subtype of the offer being passed to this function. As a result, it should work properly with any of them and apply discounted rate accordingly.
- There should not be any subtype with exception of not having any discounted price which could potentially violate LSP.
- Also, there should not be any explicit condition for any specific offer(for example, ‘Flat50’ only applicable to premium customers). If it is the case, it is subject to violation of LSP and ultimately wrong choice of abstraction is responsible for the same.
How LSP can be beneficial?
- Code readability because each offer subtype gives clear indication of its usage/purpose.
- Code reusability because we just have to rely on one common method with parameter of type ‘Offer’
- Reduction in tight coupling because we’re avoiding if/else ladder and conditional checks to make decision during checkout.
- We can easily add/remove different offer types in future and hence easy to scale/maintain code.
To conclude, LSP gives us the opportunity to loosely coupled code. Next article will be about 4th principle of SOLID.