Clean Code in Kotlin: Principles and Examples for Beginners

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Clean Code in Kotlin: Principles and Examples for Beginners



Clean Code is not just a trendy term, but a fundamental skill for any developer. In the Kotlin language, which combines conciseness and power, writing readable and maintainable code becomes especially important. In this article, we will break down the key principles of Clean Code as applied to Kotlin, provide practical examples, and show how to avoid common mistakes. The material is intended for beginner developers who want to write professional code from day one.



1. Naming Variables, Functions, and Classes



Proper naming is the foundation of clean code. A name should answer the questions: "What is this?" and "Why is it needed?" In Kotlin, camelCase is used for variables and functions, and PascalCase for classes and objects.



Bad example:

val x = 5fun calc(a: Int, b: Int): Int {    return a * b + 10}


Good example:

val maxRetryCount = 5fun calculateTotalPrice(basePrice: Int, tax: Int): Int {    return basePrice + tax}


Key rules:

  • Avoid abbreviations — replace usr with user, and calc with calculate.
  • Use verbs for functions — getUser(), sendEmail(), validateInput().
  • Boolean variables should be named with prefixes is, has, can — isActive, hasPermission.
  • Avoid redundant information — userList is better than listOfUsersFromDatabase.


2. SOLID Principles in Kotlin



SOLID is a set of five principles of object-oriented programming that help create flexible and easily maintainable systems. Let's look at them with Kotlin examples.



Single Responsibility

A class should have only one reason to change. Separate logic into small, specialized classes.



Bad example:

class UserManager {    fun saveUser(user: User) { /* saving to DB */ }    fun sendEmail(user: User) { /* sending email */ }    fun printReport(user: User) { /* printing report */ }}


Good example:

class UserRepository {    fun save(user: User) { /* saving to DB */ }}

class EmailService { fun send(user: User) { /* sending email */ }}

class ReportPrinter { fun print(user: User) { /* printing report */ }}


Open/Closed

Classes should be open for extension but closed for modification. Use interfaces and inheritance.



interface Shape {    fun area(): Double}

class Circle(val radius: Double) : Shape { override fun area() = Math.PI * radius * radius}

class Rectangle(val width: Double, val height: Double) : Shape { override fun area() = width * height}

// Now you can add new shapes without changing existing code


Liskov Substitution

Objects of subclasses should be able to replace objects of the base class without breaking the logic. In Kotlin, this is especially relevant when working with collections and inheritance.



open class Bird {    open fun fly() = "Flying"}

class Penguin : Bird() { override fun fly() = throw UnsupportedOperationException("Penguins cannot fly")}// This violates the principle — it's better to move the "ability to fly" into a separate interface


3. Working with Functions: Conciseness and Purity



Kotlin offers powerful tools for writing clean functions. Basic rules: