Piyush talks about SOLID Principles
Tags: android, java, design, kotlin
Published: 2020-04-14 13:21:49

![Just making sure](https://dev-to-uploads.s3.amazonaws.com/i/jyxfh6gp01b7frr6698d.jpeg)

This has to be one of the common questions you would hear in an interview. But there obviously you'll have only 5 minutes to prove that you know this.

I’m here to make you sure that you've got this!
__SOLID__ is one of the most important acronyms in the world of Object-Oriented Programming.

Why should you care about SOLID programming?
First of all, you have to realize you are not going to be forever where you are. If we use standards and well-known architectures, we can be sure that our code will be easy to maintain by other developers that come after us, and I’m sure you wouldn’t want to deal with the task of fixing a code that didn’t apply any known methodology as it would be very hard to understand it.

Let's jump right in.

![I know you've been waiting](https://dev-to-uploads.s3.amazonaws.com/i/xasxyr749oasldc073ks.gif)

What does SOLID stand for?
__S__ — Single Responsibility Principle.
__O__ — Open Closed Principle.
__L__ — Liskov Substitution Principle.
__I__ — Interface Segregation Principle.
__D__ — Dependency Inversion Principle.

__Single Responsibility Principle:__

_A class should have only one reason to change._

As its name suggests, this principle implies that a class/module must do only one thing, have only one responsibility. If our class does more than one thing, then we should split the functionalities into different classes.
In the context of the Single Responsibility Principle (SRP), we define responsibility as “a reason for change”. If you can think of more than one motive for changing a class, then that class has more than one responsibility.

__Example.__ Let's suppose we have a _Phone_ which has different functions like Calling, Messaging, Calculator, FlashLight, etc. Now when we define this class, we’ll have one Phone.java file, which will contain all the functions. Now, this class violates the SRP Principle as this class has been assigned multiple responsibilities. To make the class stop violating the principle, we should define the responsibilities in separate classes like Calling.java, Messaging.java, Calculator.java, thus making short components/classes and dividing the responsibilities.

__Android specific Example.__ The method _onBindViewHolder_ of the _RecyclerView_ widget. The role of the _onBindViewHolder_ is to map a list item to a view. There should be no logic in this method. So if there's any code that relates to the logic, you should probably remove from there.


__Open Closed Principle:__

_Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification._

This basically means that we should add extension points in classes that implement requirements that are intrinsically unstable due to instability in the business domain and refactor parts of code and introduce additional extension points when these parts proved to be unstable.

__Android specific Example.__ Extending _RecyclerView.Adapter_ class is easy and we can easily create custom adapters. Developers can easily extend this class and create their own custom adapter with custom behavior without modifying the existing _RecyclerView.Adapter_ class.
Another Example. can be looking at _Buttons_, _Switches_, _Checkboxes_ inherit all from _TextView_ class. This means that _TextView_ is open to extension but closed for modifications.


__Liskov Substitution Principle:__

_Objects in a program should be replaceable with instances of their subtypes without changing the behavior of that program._

This means that a subclass should override the methods from a parent class that does not break the functionality of the parent class.

__Example.__ In mathematics, a Square is a Rectangle. Indeed it is a specialization of a rectangle. The “is a” makes you want to model this with inheritance. However if in code you made Square derive from Rectangle, then a Square should be used anywhere you expect a Rectangle. This makes for some strange behavior. Imagine you had SetWidth and SetHeight methods on your Rectangle base class; this seems perfectly logical. However, if your Rectangle reference pointed to a Square, then SetWidth and SetHeight do not make sense because setting one would change the other to match it. In this case, Square fails the Liskov Substitution Test with Rectangle and the abstraction of having Square inherit from Rectangle is a bad one.

__Android specific Example.__ We should write the custom RecyclerView adapter class in such a way that it still works with RecyclerView. We should not write something which will lead the RecyclerView to misbehave.


__Interface Segregation Principle:__

_Classes that implement interfaces, should not be forced to implement methods they do not use._

This means that if an interface becomes too fat, then it should be split into smaller interfaces so that the client implementing the interface does not implement methods that are of no use to it.
ISP relates to important characteristics — cohesion and coupling.
Ideally, your components must be highly tailored. It improves code robustness and maintainability.

Enforcing ISP gives you the following bonuses:
__High cohesion__— better understandability, robustness.
__Low coupling__ — better maintainability, high resistance to changes.

Example. Again going to the previous example of Phone, if we have a public interface for the whole functionality, like this:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/15n6cgr919jfplx8lfx8.png)

Now if you want to implement a Calculator, the functions _dial()_,_lightOn()_ and _lightOff()_ are useless. Thus we should refactor the code to something like this:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ze7z65frtw30zj2m09l9.png)

Now, the desired class can implement one or more interfaces according to wish. This is how we can prevent violating ISP.

__Dependency Inversion Principle:__

_High-level modules should not depend on low-level modules. Both should depend on abstractions._

and

_Abstractions should not depend on details. Details should depend on abstractions._

If you use a class inside another class, this class will be dependent on the class injected. The importance of DIP can be distilled down to a singular goal of being able to reuse software components that rely upon external dependencies for a portion of their functionality.

__Example.__ If we have a class Bank that has the following code, the calling class of Bank is unaware of the hidden dependencies, thus this violates DIP.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dvnhoxy4x6ulx6xslf71.png)

On another hand, if we refactor the code to something like this:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dujs7lesovxphlcxgmbi.png)


In this case, we are letting the calling class of Bank aware of the dependencies involved, instead of letting the class itself create a dependency. This also helps in the case of testing!

__Conclusion:__
The _SOLID_ Principles, are some of the most important set of principles to learn and implement if you are following Object-Oriented Design. It may seem a bit overwhelming initially, but with practice and time, you will be coding based on these principles, without even realizing it. (Copied from StackOverflow :D)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/pivl181g8ebonberps8r.gif)
 
Enjoy! Happy coding!
Feel free to leave a comment if something is not clear or if you have questions.

-Piyush Maheswari.

In case you want to reach out: [Twitter](https://twitter.com/OnlyMaheswari)