Clean Code на Kotlin: принципы и примеры для чистого кода
Чистый код — это не просто модное слово, а фундаментальный навык профессионального разработчика. Когда вы пишете на Kotlin, современном и выразительном языке, принципы Clean Code становятся еще более актуальными. Код, который легко читать, изменять и поддерживать, экономит часы отладки и облегчает жизнь всей команде. В этой статье мы разберем ключевые принципы Clean Code в Kotlin с конкретными примерами, которые помогут вам писать элегантный и надежный код.
1. Именование: говорите на языке предметной области
Правильное именование — основа чистого кода. Имена переменных, функций и классов должны сразу отвечать на вопросы «что это?» и «для чего это?». Избегайте однобуквенных сокращений и абстрактных имен вроде data или temp.
Плохой пример:
val d = mutableListOf<String>()fun prc(u: User) { d.add(u.name) if (u.age > 18) println(u.name)}Хороший пример:
val registeredUserNames = mutableListOf<String>()
fun printAdultUserName(user: User) { registeredUserNames.add(user.name) if (user.isAdult()) { println(user.name) }}В хорошем примере сразу понятно, что делает функция и какие данные хранятся в списке. Используйте существительные для классов (UserRepository), глаголы для функций (processOrder) и предикаты для булевых значений (isActive, hasPermission).
2. Функции: маленькие, с одной целью и без побочных эффектов
Одна из главных идей Clean Code — функция должна делать только одну вещь. Если функция превышает 15-20 строк, скорее всего, её нужно разбить. Kotlin с его функциями-расширениями и лямбдами отлично подходит для этого.
Пример: разбиение сложной функции
Предположим, у нас есть функция для обработки заказа:
fun processOrder(order: Order) { // Валидация if (order.items.isEmpty()) throw IllegalArgumentException("Заказ должен содержать товары") if (order.totalPrice < 0.0) throw IllegalArgumentException("Некорректная цена") // Расчет скидки var finalPrice = order.totalPrice if (order.user.isPremium) { finalPrice *= 0.9 } // Отправка уведомления emailService.send(order.user.email, "Ваш заказ подтвержден") smsService.send(order.user.phone, "Заказ #${order.id} подтвержден")}Рефакторинг в соответствии с принципами Clean Code:
fun processOrder(order: Order) { validateOrder(order) val finalPrice = calculateFinalPrice(order) sendOrderConfirmation(order, finalPrice)}
private fun validateOrder(order: Order) { require(order.items.isNotEmpty()) { "Заказ должен содержать товары" } require(order.totalPrice >= 0.0) { "Некорректная цена" }}
private fun calculateFinalPrice(order: Order): Double { return if (order.user.isPremium) order.totalPrice * 0.9 else order.totalPrice}
private fun sendOrderConfirmation(order: Order, finalPrice: Double) { val message = "Заказ #${order.id} подтвержден. Итого: $finalPrice" notificationService.notifyUser(order.user, message)}Теперь каждая функция отвечает за одну задачу, их легко тестировать и переиспользовать.
3. Null Safety: используйте возможности Kotlin
Одна из главных особенностей Kotlin — null safety. Чистый код на Kotlin подразумевает полное исключение null там, где это возможно. Избегайте использования !! (not-null assertion) — это почти всегда признак плохого дизайна.
Плохой пример:
fun getUserName(userId: String): String { val user = userRepository.findById(userId)!! return user.name!!}Хороший пример:
fun getUserName(userId: String): String? { val user = userRepository.findById(userId) ?: return null return user.name}