Clean Code на Kotlin: принципы и примеры для начинающих

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Clean Code на Kotlin: принципы и примеры для начинающих

Чистый код (Clean Code) — это не просто модный термин, а фундаментальный навык любого разработчика. На языке Kotlin, который сочетает в себе лаконичность и мощь, написание читаемого и поддерживаемого кода становится особенно важным. В этой статье мы разберем ключевые принципы Clean Code применительно к Kotlin, приведем практические примеры и покажем, как избежать типичных ошибок. Материал рассчитан на начинающих разработчиков, которые хотят писать профессиональный код с первого дня.

1. Именование переменных, функций и классов

Правильное именование — основа чистого кода. Имя должно отвечать на вопросы: "Что это?" и "Зачем это нужно?". В Kotlin принят camelCase для переменных и функций, и PascalCase для классов и объектов.

Плохой пример:

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

Хороший пример:

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

Ключевые правила:

  • Избегайте сокращений — usr лучше заменить на user, а calc на calculate.
  • Используйте глаголы для функций — getUser(), sendEmail(), validateInput().
  • Булевы переменные называйте с префиксами is, has, can — isActive, hasPermission.
  • Избегайте излишней информации — userList лучше, чем listOfUsersFromDatabase.

2. Принципы SOLID в Kotlin

SOLID — это пять принципов объектно-ориентированного программирования, которые помогают создавать гибкие и легко поддерживаемые системы. Рассмотрим их на примерах Kotlin.

Single Responsibility (единственная ответственность)

Класс должен иметь только одну причину для изменения. Разделяйте логику на маленькие, специализированные классы.

Плохой пример:

class UserManager {
    fun saveUser(user: User) { /* сохранение в БД */ }
    fun sendEmail(user: User) { /* отправка письма */ }
    fun printReport(user: User) { /* печать отчета */ }
}

Хороший пример:

class UserRepository {
    fun save(user: User) { /* сохранение в БД */ }
}

class EmailService {
    fun send(user: User) { /* отправка письма */ }
}

class ReportPrinter {
    fun print(user: User) { /* печать отчета */ }
}

Open/Closed (открытость/закрытость)

Классы должны быть открыты для расширения, но закрыты для модификации. Используйте интерфейсы и наследование.

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
}

// Теперь можно добавлять новые фигуры, не меняя существующий код

Liskov Substitution (подстановка Лисков)

Объекты подклассов должны заменять объекты базового класса без нарушения логики. В Kotlin это особенно актуально при работе с коллекциями и наследованием.

open class Bird {
    open fun fly() = "Летит"
}

class Penguin : Bird() {
    override fun fly() = throw UnsupportedOperationException("Пингвины не летают")
}
// Это нарушение принципа — лучше вынести "умение летать" в отдельный интерфейс

3. Работа с функциями: лаконичность и чистота

Kotlin предлагает мощные инструменты для написания чистых функций. Основные правила:

  • Функции должны быть маленькими — не более 20-30 строк.
  • Одна функция — одна задача.
  • Используйте именованные аргументы для улучшения читаемости.
  • Избегайте побочных эффектов (side effects) — функции не должны изменять глобальное состояние.

Пример чистой функции:

fun calculateDiscount(price: Double, discountPercent: Double): Double {
    return price * (1 - discountPercent / 100)
}

// Использование с именованными аргументами
val finalPrice = calculateDiscount(price = 100.0, discountPercent = 15.0)

Используйте extension functions для улучшения читаемости:

fun String.isValidEmail(): Boolean {
    return this.contains("@") && this.contains(".")
}

// Использование
val email = "test@example.com"
if (email.isValidEmail()) {
    println("Email корректен")
}

4. Null Safety и работа с nullable типами

Одна из главных фишек Kotlin — встроенная защита от NullPointerException. Чистый код требует грамотного использования nullable типов.

Плохой пример:

fun processUser(user: User?) {
    if (user != null) {
        println(user.name)
    }
}

Хороший пример (с использованием scope-функций):

fun processUser(user: User?) {
    user?.let {
        println(it.name)
        // Безопасная работа с user
    }
}

// Или с использованием элвис-оператора
fun getUserName(user: User?): String {
    return user?.name ?: "Гость"
}

Рекомендации:

  • Избегайте использования !! (not-null assertion) — это почти всегда запах плохого кода.
  • Используйте ?.let, ?: (elvis) и ?.run для безопасной работы.
  • Проектируйте API так, чтобы nullable типы были исключением, а не правилом.

5. Форматирование и структура кода

Единообразие форматирования повышает читаемость. В Kotlin приняты следующие правила:

  • Отступы —

Блоги

Рекомендаций по книгам