S.O.L.I.D Principles: The Kotlin Way

Vijay Mishra
The Android Cafe
Published in
4 min readJul 24, 2021

In software engineering, SOLID is a mnemonic acronym for five design principles intended to make software designs more understandable, flexible, and maintainable.

Single Responsibility principle

The Single responsibility Principle states that every class should have one and only one responsibility. In other words, If there is a need to change the class for more than one reason then that defies the single responsibility principle.

For Example, Let’s take a look at the User class below which holds the information about the user along with sign-in and sign-out methods for the user to manage the authentication process.

Now let's assume that we need to make some changes for the authentication process in sign-in and sign-out methods, Our user class will get affected. Which added more than one responsibility to one class.

When such scenarios occur we should separate our classes. This means the User class should only have one responsibility i.e. to hold user information.

To solve the issue we should create a new class to manage the authentication process and move the sign-in and sign-out function in that class.

Open-Closed Principle

This principle has two meanings.

  • Open: This means that we can add new features to our classes. When there is a new requirement, we should be able to add new features to our class easily.
  • Close: This means that the base features of the class should not be changed.

Let’s take an example.

The code below has a class named area factory which calculates the area of a shape. Having a close look at the code we see that we have an if-else statement to separate out the shapes, and as the shapes increase they will continue to grow that way Because the class is not closed for modification, and neither it is open for extension. Hence it is violating our open-closed principle.

We will fix this with the help of the interface.

Now, If we look at the code above after adding an interface. If we need to add more shapes the AreaFactory class does not require any changes because it is open for extension through the Shape Interface.

Liskov Substitution Principle

We should be able to use subclasses instead of the parent classes which class they have extended, without the need to make any changes in our code. In simple words, the child class must be substitutable for the parent class.
Since child classes extended from the parent classes, they inherit their behavior.

If child classes can not perform the behaviors belonging to the parent classes, probably, we won’t write any code in the method that does the behavior or we will throw an error when objects want to use it. But these actions cause code pollution and unnecessary code crowds.

Let’s assume that we have an abstract class named Vehicle. This abstract class has some methods. When we create child classes such as Car, Truck and etc. to extend the Vehicle abstract class will be fine for us.

In the above code as you can see when we create the Bicycle class the methods start engine and stop engine are useless as the Bicycle does not have an engine.

To fix this situation, we can create a new child class that will extend the Vehicle. This class will work with vehicles that will have an engine.

Interface Segregation Principle

This principle states that once an interface becomes too fat, it needs to be split into smaller interfaces so that client of the interface will only know about the methods that pertain to them.
So let’s think that we have an animal interface. And this interface will have methods about behaviors that animals do.

As you can see, in the above example that some animals can’t fly such as cats. So it will be unnecessary to implement the fly method.
To fix that issue, We will create a new Interface for flying animals and will remove the fly method from the animal interface.

Dependency Inversion Principle

This principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions and Abstractions should not depend upon details. Details should depend upon abstractions.

Let’s assume that we need to develop a mobile application for both Android and iOS. To do that, we need an Android Developer and an iOS Developer. These classes will have a method to develop a mobile application by using their own platform and programming language.

To fix the problem here, we can create an interface, and AndroidDeveloper and IosDeveloper classes will implement this interface.

That’s it for SOLID principles. It is easy when you understand these principles with simple examples rather than by definition.

Until next time. Follow for more awesome upcoming content on android development. 👋 ☮️

--

--