Introdução: por que o código limpo é importante em Kotlin
\n\nCódigo limpo (Clean Code) não é apenas um termo da moda, mas uma habilidade fundamental para o desenvolvedor profissional. No ecossistema Kotlin, que combina programação orientada a objetos e funcional, os princípios de código limpo adquirem especial importância. Kotlin oferece ferramentas poderosas (null safety, extension functions, sealed classes) que, quando usadas corretamente, tornam o código conciso e seguro. No entanto, sem uma abordagem consciente da limpeza, essas mesmas possibilidades podem levar à confusão.
\n\nNeste artigo, abordaremos os princípios-chave do Clean Code em Kotlin com exemplos reais. Você aprenderá como evitar antipadrões típicos, escrever código autodocumentado e usar os recursos da linguagem para aumentar a legibilidade e a sustentabilidade dos projetos.
\n\n1. Nomenclatura e estrutura: legibilidade em primeiro lugar
\n\nNomes corretos — metade do sucesso
\nUm bom nome de variável, função ou classe deve responder às perguntas "O que é isso?" e "Para que serve?". Evite abreviações e nomes de uma letra (exceto para índices de loops). Em Kotlin, é especialmente importante usar nomes claros, pois o código geralmente contém cadeias de chamadas.
\n\n// Ruim: nomes não informativos\nfun calc(a: Int, b: Int): Int = a * b\n\n// Bom: o nome reflete a essência\nfun calculateRectangleArea(width: Int, height: Int): Int = width * height\n\nEstrutura de arquivos e classes
\nEm Kotlin, é comum agrupar funções e classes relacionadas em um único arquivo. Use pacotes para separação lógica. Evite "classes-deus" — divida a lógica em entidades pequenas e focadas.
\n\n// Ruim: uma classe faz tudo\nclass UserManager {\n fun registerUser(...) { /*...*/ }\n fun sendEmail(...) { /*...*/ }\n fun generateReport(...) { /*...*/ }\n}\n\n// Bom: separação de responsabilidades\nclass UserRegistrationService {\n fun registerUser(...) { /*...*/ }\n}\n\nclass EmailService {\n fun sendEmail(...) { /*...*/ }\n}\n\nclass ReportGenerator {\n fun generateReport(...) { /*...*/ }\n}\n\n2. Null Safety e tratamento de erros: segurança sem ruído
\n\nUse os recursos do Kotlin para segurança contra nulos
\nKotlin elimina o NullPointerException em nível de compilação. Não abuse do operador !! — isso é um antipadrão. Em vez disso, use chamadas seguras (?.) e o operador elvis (?:).
// Ruim: risco de NPE\nfun getUserName(user: User?): String {\n return user!!.name\n}\n\n// Bom: chamada segura com valor padrão\nfun getUserName(user: User?): String {\n return user?.name ?: "Unknown"\n}\n\nSealed classes para modelagem de estados
\nQuando uma função pode retornar vários tipos de resultados, use sealed class em vez de exceções ou valores nulos. Isso torna o tratamento explícito e seguro.
sealed class NetworkResult<out T> {\n data class Success<T>(val data: T) : NetworkResult<T>()\n data class Error(val message: String, val code: Int) : NetworkResult<Nothing>()\n object Loading : NetworkResult<Nothing>()\n}\n\nfun fetchUser(): NetworkResult<User> {\n return try {\n val user = api.getUser()\n NetworkResult.Success(user)\n } catch (e: Exception) {\n NetworkResult.Error("Failed to fetch user", 500)\n }\n}\n\n// Uso\nwhen (val result = fetchUser()) {\n is NetworkResult.Success -> showUser(result.data)\n is NetworkResult.Error -> showError(result.message)\n is NetworkResult.Loading -> showLoader()\n}\n\n3. Funções: pequenas, limpas e com um único propósito
\n\nRegra de responsabilidade única para funções
\nCada função deve fazer apenas uma ação. Se a função contém a palavra "e" na descrição — provavelmente precisa ser dividida. Em Kotlin, isso é especialmente fácil graças às funções de extensão.