👨‍💻Kotlin SOLID Principles

Hi! What are SOLID principles and why should developers use them? 🕵️‍♀️

Hüseyin Özkoç
Huawei Developers
5 min readApr 13, 2023

--

Kotlin SOLID Principles

😮Many Kotlin developers do not have full knowledge of SOLID principles, and even if they know, they are not aware of why it is used. Are you ready to learn all the details?

Introduction

Hello Dear Kotlin lovers! Welcome to my new article. Today I am going to talk about SOLID principles in Kotlin. First of all, I will explain with examples what SOLID principles are and what they are used for.

What are SOLID Principles?

SOLID is an acronym for five design principles that help create maintainable, scalable, and robust software. Robert C. Martin introduced these principles to guide programmers in producing high-quality code. Although initially for object-oriented programming, SOLID is also applicable to other languages like Kotlin. The principles aim to promote clean code and improve software design. The SOLID principles are as follows:

  1. Single Responsibility Principle
  2. Open/Closed Principle
  3. Liskov Substitution Principle
  4. Interface Segregation Principle
  5. Dependency Inversion Principle

Now, if you are ready, let’s look these principles in detail with examples of correct usage and violations.

Single Responsibility Principle

The principle of Single Responsibility (SRP) is a part of SOLID programming principles in object-oriented programming. It signifies that a particular class should have only one purpose to change. It means that a class should possess only one responsibility or a job. SRP is useful in maintaining classes and functions by keeping them organized and easy to comprehend. When a class has multiple responsibilities, these can unintentionally affect other tasks or jobs of that class, resulting in unexpected behavior, bugs, and increased maintenance costs.

Now let’s look at the violation situation and its correct usage.

Violation:

Single Responsibility Principle Violation

In this example the System class is trying to handle many different situation at the same place. This approach can cause major problems in the future.

Correct Usage:

Single Responsibility Principle Correct Usage

As seen in this example, we divided our System class into specific parts and placed the functions in their respective classes.

Open/Closed Principle

The Open/Closed Principle is a rule in object-oriented design that says classes, modules, functions, and other software entities should be open for extension but closed for modification. This means you can add new things to a class without changing its original code. So instead of changing the class itself, you can write new code that uses the existing class to add new features. Doing this makes the code easier to maintain and reuse.

Now let’s look at the violation situation and its correct usage.

Violation:

Open/Closed Principle Violation

In this example, when we try to add something new to our class, we have to rewrite our existing code, which can cause problems later on.

Correct Usage:

Open/Closed Principle Correct Usage

As in correct usage, instead of changing the class itself, we wrote new classes using our existing class and implemented our functions under new classes.

Liskov Substitution Principle

The Liskov Substitution Principle is an important rule in object-oriented programming. It says that if you have a program that works with a certain type of object, you should be able to use any subtype of that object without any problems. This means that all the methods and properties in the main class should also work for all the sub-classes without needing to change anything.

Now let’s look at the violation situation and its correct usage.

Violation:

Liskov Substitution Principle Violation

As we saw in this example, the method we wrote in our main class should work properly in its subclasses according to the Liskov principle, but when our subclass inherited from our superclass, our fly method did not work as expected.

Correct Usage:

Liskov Substitution Principle Correct Usage

As you can see in this example, all the things we write in the superclass will be valid in the subclasses, because we have implemented the method that is not valid for subclasses by creating an interface and implementing that interface where we need it.

Interface Segregation Principle

The Interface Segregation Principle is a rule for making computer programs. It says that when we make different parts of a program, we shouldn’t make them all the same way. Instead, we should make them smaller and more specific, so that other parts of the program don’t have to depend on things they don’t need. This helps us make code that’s easier to change and take care of, because each part only does what it needs to do.

Now let’s look at the violation situation and its correct usage.

Violation:

Interface Segregation Principle Violation

When we look at our example, we see that the interface we created contains many methods. If we do everything inside a common interface, we may have made unnecessary use in the places that implement our interface. Instead, we can divide our system into smaller interface parts.

Correct Usage:

Interface Segregation Principle Correct Usage

As we saw in the correct usage example, dividing the system into smaller interfaces and using them where we needed them made it much easier to change the system in the future.

Dependency Inversion Principle

The Dependency Inversion Principle is a SOLID principle that states that high-level modules should not depend on low-level modules, but both should depend on abstractions. This means that classes should depend on abstractions, not on concrete implementations. The idea behind DIP is to decouple components from each other, which makes the code more modular, easier to test, and more maintainable.

Now let’s look at the violation situation and its correct usage.

Violation:

Dependency Inversion Principle Violation

As we can see in this example, each of our payment methods is processed separately in our Service class in a hard code way. Instead of a hard code implementation, the system needed to be depend to an abstract structure.

Correct Usage:

Dependency Inversion Principle Correct Usage

In the correct usage example, we did not have to implement hard code about our payment methods in our Service class, because we set up an abstract structure with the interface that we created.

Conclusion

As a result, the SOLID principles are essential for creating maintainable, scalable, and efficient software in Kotlin. Leveraging Kotlin’s unique features and constructs, developers can design modular, loosely coupled systems that adhere to these guidelines. Adhering to the SOLID principles not only improves code testability but also encourages a culture of continuous improvement and best practices. Ultimately, employing these principles in Kotlin development results in higher-quality software that can be effectively maintained and adapted to evolving requirements.

Photo by Fotis Fotopoulos on Unsplash

References

--

--