Skip to content

Latest commit

 

History

History
128 lines (77 loc) · 19 KB

Solid_Principles.md

File metadata and controls

128 lines (77 loc) · 19 KB

SOLID Principles

In this section will discuss what's SOLID principles, what problems it solves & how we identify and solve the problem by keeping these principles in mind.


Principle Name Description
Single Responsibility Principle Class must be responsible to server only one duty
Open-Closed Principle Class must be open for extension but strictly not for modification
Liskov Substitution Principle The object of the Child class must be replaceable with the object of the parent class without breaking the system
Dependency Inversion Principle High/low level module must not be dependent on each other, they must be dependent on abstraction

1. Single Responsibility Principle

This principle says that every class should have well defined and unique responsibility.

Let's take an example of banking service. If you have single BankService class doing operations like

then you are violating the SRP principle because in future there could be requirements where above implementations will be changes in "BankService" class. If you are modifying the class for the new requirements that mean you are violating SRP principle.

How to implement "Single Responsibility Principle" ?

  • Keep only core banking related operations like
    1. deposit
    2. withdraw in the "BankService" class

  • for other operations like
    1. sendOTP - create "NotificationService" class
    2. getLoanInfo - create "LoanService" class
    3. createDemateAccount - create "DemateAccountService" class
    4. and so on.... and move the methods in above classes respectively.

2. Open Closed Principle

This principle says that every class should be open for extension but close for the modification.

Suppose in above example we want to add Instagram notification feature in NotificationService. By doing this we are violating OCP principle. We should not modify existing BAU rather we should design our code in such a way that we can achieve it by creating new class and implementing some interface.

How to implement "Open Closed Principle" ?

To implement OCP principle in above scenario, we can create one interface having common methods for all such notification implementations.

Here NotificationService interface will define the behavior of the implementation and class who will implement this interface need to provide the business logic according to their requirements.

By doing this we are not modifying existing BAU of any other class whenever new requirement comes which is the main goal of this principle.

3. Liskov substitution principle

This principle says that one should develop the inheritance hierarchy in such a way base class must be substitutable by its child class.

To understand this principle we will take an example of social media. Suppose we have abstract class SocialMedia as follow:

Now suppose we want to create following applications:

  1. Facebook
    • chatWithFriends
    • publishPost
    • sendPhotosAndVideos
    • groupVideoCall
  2. WhatsApp
    • chatWithFriends
    • sendPhotosAndVideos
    • groupVideoCall
  3. Instagram
    • chatWithFriends
    • publishPost
    • sendPhotosAndVideos

So we will extend the abstract class and implement methods.

Here we can substitute SocialMedia with FaceBook class because all the methods are subsitutable. But the same is not true for Instagram & Whatsapp because not all the methods are required and substitutable between SocialMedia & Instagram/Whatsapp.

so that's where LSP comes into the picture and solves our problem.

How to implement "Liskov substitution principle" ?

Identify responsibility and create interface accordingly. Use these interfaces as per the requirement and then parent class will be replaceable by the child class.

Create following interfaces and implement as per the requirements:

4. Interface Segregation principle

This princile says that DO NOT FORCE class to implement all the methods from inteface IF IT DOSE NOT REQUIRE

Check below example of UPIManager :

Here Gpay & Paytm does not want to implement getCashBack(). So for that we can create another interface and move the getCashBack() method into that class.

Check following class diagram for solution using Interface Segregation principle.

5. Dependency inversion principle

High/low level module must not be dependent on each other, they must be dependent on abstraction

When you go for shopping and pay your bills using credit/debit card, the cashier does not care about if it is credit/debit card or the card is of which company ? It simply swipe the card for the payment and it happens (if enough balance is there, of-course :p)

ShoppingMall HAS-A BankCard which can be type of Debit or Credit card. And Debit/Credit card will be implementing the doTransaction method from BankCard interface.