Refatoração de código legado em Kotlin: técnicas e práticas avançadas

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que refatorar código legado em Kotlin não é apenas reescrever



Trabalhar com código legado em Kotlin não é apenas uma substituição mecânica de construções Java pela sintaxe da linguagem. É um processo estratégico, voltado para aumentar a legibilidade, segurança e desempenho do código sem alterar seu comportamento externo. Neste artigo, veremos técnicas avançadas de refatoração que ajudarão você a transformar um "zoológico" caótico de classes em um sistema organizado e sustentável. Não abordaremos conceitos básicos como var vs val — focaremos no que realmente muda a arquitetura.



1. Migração de Java: substituindo getters, setters e classes utilitárias



O problema mais comum em código legado é a abundância de classes Java com getters e setters explícitos, além de classes utilitárias estáticas. Kotlin oferece soluções elegantes.



1.1. Acesso baseado em propriedades em vez de JavaBeans



Em vez de escrever user.getName() e user.setName("Alice"), use propriedades do Kotlin. Isso não é apenas açúcar sintático: você obtém uma interface de acesso unificada que pode ser sobrescrita.



// Java legadopublic class User {    private String name;    public String getName() { return name; }    public void setName(String name) { this.name = name; }}

// Kotlin refatoradodata class User(val name: String) // Ou com var, se precisar de mutabilidade


Se a lógica do getter/setter for mais complexa (por exemplo, validação), use assessores personalizados:



class User {    var name: String = ""        set(value) {            field = value.trim() // Corte automático de espaços        }}


1.2. Funções extension em vez de utilitários estáticos



Código legado frequentemente contém classes como StringUtils ou FileUtils. Em Kotlin, elas são substituídas por funções extension. Isso torna o código mais legível e se aproxima do estilo "método do objeto".



// Java: StringUtils.isNullOrEmpty(str)// Kotlin: str.isNullOrEmpty() (já existe na stdlib)

// Exemplo de sua própria extensionfun String.isValidEmail(): Boolean { return this.contains("@") && this.contains(".")}

// Usoval email = "user@example.com"if (email.isValidEmail()) { ... }


2. Trabalhando com null safety: substituindo Optional e verificações de null



Código legado em Java frequentemente sofre de NullPointerException. Kotlin resolve esse problema no nível de tipos, mas durante a refatoração é preciso substituir cuidadosamente Optional e cadeias de verificações de null.



2.1. Substituindo Optional por tipos nullable



Em vez de Optional<String>, use String?. Isso reduz a sobrecarga de criação de objetos e torna o código mais conciso.



// Javapublic Optional<String> findName() { ... }

// Kotlinfun findName(): String? { ... }


Para cadeias de chamadas, use o operador ?. e o operador elvis ?::



// Em vez de if (user != null && user.address != null) ...val city = user?.address?.city ?: "Unknown"


2.2. Usando require() e check() para invariantes



Em vez de verificações manuais no início das funções, use funções embutidas:



fun processUser(user: User?) {    requireNotNull(user) { "User must not be null" }    // ou require(user != null) { ... }    // Trabalho posterior com user (smart cast)}


3. Refatoração de lógica condicional: classes sealed e when



Blocos enormes de if-else ou switch são um sinal de código legado. Em Kotlin, eles podem ser substituídos por sealed class e when exaustivo.



3.1. Substituindo enum com campos por sealed class



Se você tem um enum que armazena diferentes tipos de dados para cada valor

Blogs

Book Recommendations