ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Follow publication

Exploring S.O.L.I.D Principle in Android

We must all have heard about the S.O.L.I.D principle when developing software tools. I recently had a interview experience where this was asked and I wasn’t very clear on it. So I took the the time to fully understand what S.O.L.I.D means. I just wanted to highlight the basics of the principle and provide some examples on how this would be applicable to Android development.

So let’s begin by stating the 5 principles of S.O.L.I.D.

S — The Single Responsibility Principle (SRP):

A class should have only one reason to change

What I understood :This means that one class should only have one responsibility.

Scenario: Let’s take the OnBindViewHolder method in RecyclerView.Adapter class. The role of the OnBindViewHolder is to map an list item to a view. There should be no logic in this method.

Let’s look at the below example to see how the SRP principle is violated in the OnBindViewHolder method in this scenario:

OnBindViewHolder has only one responsibility which is to display data & not make data formatting operations

Now, let’s look at the correct way to implement the OnBindViewHolder method using SRP principle:

All the logic is moved into the Util class. So now the code is clean!

O — The Open-Closed Principle (OCP):

Software entities such as classes, functions, modules should be open for extension but not modification.

What I understood: This means that if we are required to add a new feature to the project, it is good practice to not modify the existing code but rather write new code that will be used by the existing code.

Scenario: Let’s say we have a class called TimeOfDayGreeting with a single method getGreetingFromTimeOfDay. We would like to display a greeting message when the user opens the app. This message must be based on the time of the day.

Let’s look at the below example to see how the OCP principle is violated in this scenario:

Every time this method is called, if else condition will be executed, which violates the OCP principle

Now, let’s look at the correct way to implement this feature using the OCP principle:

Created an interface to handle action. Created 4 different classes for 4 different times of the day. The TimeOfDayGreeting class does not handle any logic now.

L —The Liskov Substitution Principle (LSP):

Child classes should never break the parent class’ type definitions.

What I understood: This means that a sub class should override the methods from a parent class that does not break the functionality of the parent class.

Scenario: Let’s say we have a interface ClickListener. This interface is implemented by the fragments 1 & 2. We would need to implement the ClickListener interface in both the fragments. Our requirement is to increment click count in fragment 2 but decrement click count in fragment 1.

Let’s look at the below example to see how the LSP principle is violated in this scenario:

Bad Practice of LSP principle

Now, let’s look at the correct way to implement this feature using the LSP principle:

Good practice of LSP principle

I — The Interface Segregation Principle (ISP):

The interface-segregation principle (ISP) states that no client should be forced to depend on methods it does not use.

What I understood: 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.

Scenario: Let’s take the TextWatcher interface in Android. We know that the TextWatcher interface has 3 methods. This is an example of how this principle is violated, since we only use one of the methods most of the time.

Bad practice of ISP principle

Now, let’s look at the correct way to implement this feature using the ISP principle:

Good practice of ISP principle

D — The Dependency Inversion Principle (DIP):

High-level modules should not depend on low-level modules. Both should depend on abstractions.
Abstractions should not depend upon details. Details should depend upon abstractions.

What I understood: If you use a class insider another class, this class will be dependent of the class injected.

Scenario: Let’s say we have a class called JobTracker. The requirement is to update users via email or call based on the urgency of the job.

Let’s look at the below example to see how the DIP principle is violated in this scenario:

Bad example of DIP principle

Now, let’s look at the correct way to implement this feature using the DIP principle:

Good practice of DIP principle

And that’s it! If you like this and think I have done a good job here then please don’t forget to clap. Your appreciation is valuable and keeps me motivated.

Happy Coding, Cheers!!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Responses (26)

Write a response