Introdução: Por que código limpo não é um luxo, mas uma necessidade
Todo desenvolvedor já se deparou pelo menos uma vez com um código impossível de entender sem uma xícara de café e meditação. Variáveis com nomes como a, b, temp, métodos com 500 linhas de comprimento e comentários como "aqui tem magia, não mexa" — são sinais claros de que o projeto está se transformando em "legado". Clean Code (Código Limpo) é uma filosofia e um conjunto de práticas que tornam o código legível, facilmente mantível e extensível.
Neste artigo, vamos analisar os princípios-chave do Clean Code na linguagem Java com exemplos concretos. Você aprenderá como escrever código que você mesmo e seus colegas agradecerão por ler daqui a seis meses.
Princípio 1: Nomes significativos
O nome de uma variável, método ou classe deve responder a três perguntas: o que é, para que serve e como usá-lo. Um nome ruim é a principal fonte de confusão.
Exemplo ruim
public List<Integer> getList(int a) { List<Integer> list = new ArrayList<>(); for (int i = 0; i < a; i++) { list.add(i * 2); } return list;}O que este método faz? O que é a? Retorna uma lista de números pares? Ou apenas multiplica algo por dois?
Exemplo bom (Clean Code)
public List<Integer> generateEvenNumbers(int count) { List<Integer> evenNumbers = new ArrayList<>(); for (int i = 0; i < count; i++) { evenNumbers.add(i * 2); } return evenNumbers;}Agora tudo está claro sem comentários: o método gera uma lista de números pares de um determinado comprimento.
Regras de nomenclatura
- Classes: substantivos (
User,PaymentProcessor) - Métodos: verbos (
saveUser(),calculateTotal()) - Variáveis: substantivos com significado (
userName,totalPrice) - Evite: abreviações (
usrNm), nomes de uma letra (exceto contadores de loopi,j)
Princípio 2: Métodos pequenos com uma única responsabilidade
Um método deve fazer apenas uma coisa e fazê-la bem. Se um método pode ser descrito com a conjunção "E" (primeiro faz A, E depois B), então ele precisa ser dividido.
Exemplo ruim: monolítico
public void processOrder(Order order) { // Validação if (order.getItems().isEmpty()) { throw new IllegalArgumentException("Order is empty"); } // Cálculo do total double total = 0; for (Item item : order.getItems()) { total += item.getPrice() * item.getQuantity(); } // Envio de email EmailService.send(order.getCustomerEmail(), "Your order total: " + total); // Salvamento no BD orderRepository.save(order);}Este método faz 4 coisas: valida, calcula, envia email e salva. Se algo quebrar, a causa terá que ser procurada em todo o método.
Exemplo bom: métodos limpos
public void processOrder(Order order) { validateOrder(order); double total = calculateTotal(order); sendConfirmationEmail(order, total); saveOrder(order);}
private void validateOrder(Order order) { if (order.getItems().isEmpty()) { throw new IllegalArgumentException("Order cannot be empty"); }}
private double calculateTotal(Order order) { return order.getItems().stream() .mapToDouble(item -> item.getPrice() * item.getQuantity()) .sum();}
private void sendConfirmationEmail(Order order, double total) { String message = "Your order total: " + total; EmailService.send(order.getCustomerEmail(), message);}
private void saveOrder(Order order) { orderRepository.save(order);}Cada método é um bloco de construção. Eles