Solid Principles

Solid Principles

My perspective on solid principles part-2

In the previous article, Solid Principles part-1 I told you about how I have achieved SRP(Single Responsibility Principle) and OCP (Open and Closed Principle). Which is by creating a separate class for each bird, and I also mentioned that there is a catch when it comes to overriding the fly method for each bird subclass, because not every bird can fly.

yeah that's where I have implemented the interface, through this I can make only that bird implement the flyable interface which can fly and just override the method in it. The code looks something like this.

class Eagle implements Flyable{
    @override
    public void fly(){
        System.out.println("fly......");
    }
}

Let me tell you an other experience ,I was working on an assignment where i made Rectangle as a superclass and square as a subclass, as i read somewhere square is a special kind of rectangle. I mean why not I would be getting all those methods which I need in the square class from a rectangle class, so I did it this way.

class Square extends Rectangle{
    int side;
    public int getArea(){
        return this.side*this.side
    }
}
class Client{
    public static void main(String args[]){
        Square square=new Square();
    }
}

But if you can see keenly if in future if i ever wanted to do something like this :

Rectangle rec=new Square();
rec.getArea();

can I do this? the answer is No, I ended up giving special meaning to the method of the superclass. That's when I got to know about the Liskov substitution principle.

The L from solid is the Liskov substitution principle, this principle says that we should be able to replace the reference of the parent class by its subclass without breaking the code or no subclass should provide special meaning to the methods of superclass.

Going back to my previous experience which is the bird class, I had small test case scenario where I had to fulfil the requirement such that every bird which can dance can fly. In that case, I very confidently created an interface: FlyDance, But this is not a best practice because the requirement might change, that's why we must always ensure that interfaces are segregated properly and they should be as light as possible. This is where I learned about the Interface segregation principle.

Let me share another experience of how I got to know that dependency injection will help achieve dependency inversion. So I was trying to create a UPI payment Application where I created an interface for BankingServices and two classes implementing it ABC_Bank and XYZ_Bank but in the client class when i want to inject the dependency I generally go with ABC_Bank abc_bank=new ABC_Bank() in my client class but my friend asked me what if the bank changes to XYZ_Bank, you would not modify the code again and again right? That's when I read about the dependency inversion principle why not give the client class the responsibility to create an object or inject dependency based on the object I pass to the client's constructor.

class Client{
    BankingServices bankingServices;
    public Client(BankingServices bank){
        this.bankingServices=bank;
    }
}

This is how I got to know about the D from solid principles Dependency inversion principle.

Let me talk more about Design patterns in the upcoming articles, till then keep learning,try to implement best practices and enjoy programming..... Bye.