Code review em Java: o que verificar e como dar feedback
Code review (revisão de código) é uma das ferramentas mais eficazes para melhorar a qualidade do produto de software e o crescimento profissional da equipe. No entanto, quando se trata de Java, muitos desenvolvedores (especialmente juniores) têm medo de enviar seu código para revisão ou não sabem no que prestar atenção ao revisar o código de outra pessoa. Neste artigo, vamos analisar exatamente o que precisa ser verificado no código Java e como formular observações para não ofender um colega, mas ajudá-lo a melhorar.
1. O que verificar no código Java: checklist técnico
A primeira coisa que vem à mente é sintaxe e lógica. Mas a revisão profissional vai muito além disso. Aqui estão os principais aspectos que vale a pena verificar em cada pull request.
1.1. Arquitetura e design
Veja o quão bem a nova alteração se encaixa na arquitetura existente. Ela viola os princípios SOLID? Por exemplo, se você vir uma classe que faz demais (God Object), isso é motivo para sugerir sua divisão.
- Princípio da Responsabilidade Única (SRP): Cada classe deve ter um único motivo para ser alterada.
- Inversão de Dependência (DIP): Dependa de abstrações, não de implementações concretas.
- Padrões: O uso de singletons, factories ou strategies deve ser justificado, e não aplicado "por precaução".
// Ruim: a classe sabe tanto da lógica quanto da persistênciapublic class UserService { public void registerUser(String name) { // validação // salvar no BD // enviar email }}
// Bom: separação de responsabilidadespublic class UserService { private final UserRepository repository; private final EmailService emailService;
public void registerUser(String name) { User user = new User(name); repository.save(user); emailService.sendWelcome(user); }}1.2. Performance e gerenciamento de memória
Java é uma linguagem com gerenciamento automático de memória, mas isso não significa que podemos esquecer da otimização. Verifique:
- Concatenação de strings em loop: Use
StringBuilderouStringBuffer. - Objetos desnecessários: Criação de objetos temporários em loops críticos.
- Coleções: Escolha da implementação correta (ex.:
ArrayListvsLinkedList). - NullPointerException: Use
Optionalou verificações de null.
// Ruim: milhões de strings na memóriaString result = "";for (String s : list) { result += s;}
// Bom: StringBuilderStringBuilder sb = new StringBuilder();for (String s : list) { sb.append(s);}String result = sb.toString();1.3. Tratamento de erros e exceções
Um erro em Java nem sempre é um bug. Às vezes é o uso incorreto de exceções. Preste atenção:
- Blocos catch vazios:
catch (Exception e) {}é prejudicial. O erro precisa pelo menos ser registrado em log. - Exceções muito genéricas: Capturar
ExceptionouThrowableé uma má prática. - Fluxos de recursos: Use try-with-resources para fechamento automático.
// Ruim: engolir a exceçãotry { // algum código} catch (Exception e) { // não fazemos nada}
// Bom: registrar em log e relançartry { // algum código} catch (SQLException e) { log.error("Erro ao trabalhar com o BD", e); throw new ServiceException("Não foi possível executar a operação", e);}1.4. Testes e cobertura
Revisão de código sem verificar os testes é uma revisão "pela metade". Certifique-se de que: