Introdução: Por que código limpo não é um luxo, mas uma necessidade
\nTodo desenvolvedor Java já se deparou com a situação de, ao abrir um projeto antigo, passar horas tentando entender o que ele mesmo escreveu alguns meses atrás. E o que dizer do código de outras pessoas? Código sujo atrasa o desenvolvimento, aumenta o número de bugs e desmotiva a equipe. O livro "Clean Code" de Robert Martin se tornou uma bíblia para programadores, mas seus princípios muitas vezes permanecem abstratos. Neste artigo, vamos analisar os conceitos-chave do Clean Code em Java com exemplos reais que podem ser aplicados hoje mesmo.
\nCódigo limpo não é sobre sintaxe ideal ou seguir modismos. É sobre respeito aos colegas, ao seu eu futuro e, em última análise, ao negócio. Código legível é mais fácil de manter, testar e refatorar. Vamos ver como transformar código Java de "funcionando" em "limpo".
\n\n1. Nomes significativos: fale a linguagem do domínio
\nRegra: o nome deve responder às perguntas "por quê?", "o quê?", "como?"
\nNomeação ruim é o principal inimigo do código limpo. Variáveis como int a, String d ou List<Integer> list1 não transmitem informação. Um bom nome deve revelar a intenção do programador.
// Ruim\nint d; // elapsed time in days\nList<Integer> lst;\n\n// Bom\nint daysSinceCreation;\nList<Integer> customerIds;\n\nEvite desinformação
\nNão use accountList se não for uma List, mas sim um Set ou Map. Não abrevie o óbvio: usrNm em vez de userName.
Nomes de classes e métodos
\n- \n
- Classes: substantivos (
Customer,OrderProcessor). \n - Métodos: verbos (
calculateTotal(),saveToDatabase()). \n - Variáveis booleanas: predicados (
isActive,hasPermission). \n
// Ruim\npublic class Data {\n public void proc() { ... }\n}\n\n// Bom\npublic class InvoiceCalculator {\n public BigDecimal calculateTotalAmount() { ... }\n}\n\n2. Funções: curtas, atômicas e sem efeitos colaterais
\nPrimeiro princípio: a função deve fazer apenas uma coisa
\nA função ideal em Java tem de 4 a 20 linhas. Se uma função faz mais de uma ação, ela precisa ser dividida. Um sinal clássico: se você pode extrair da função outra função com um nome significativo, faça isso.
\n\n// Ruim: a função faz três coisas\npublic void processOrder(Order order) {\n if (order == null) throw new IllegalArgumentException();\n // 1. Validação\n if (order.getItems().isEmpty()) {\n logger.warn("Empty order");\n return;\n }\n // 2. Cálculo do total\n BigDecimal total = BigDecimal.ZERO;\n for (Item item : order.getItems()) {\n total = total.add(item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())));\n }\n // 3. Envio de email\n emailService.sendConfirmation(order.getCustomerEmail(), total);\n}\n\n// Bom: cada função faz uma coisa\npublic void processOrder(Order order) {\n validateOrder(order);\n BigDecimal total = calculateTotal(order);\n sendConfirmationEmail(order, total);\n}\n\nprivate void validateOrder(Order order) {\n if (order == null || order.getItems().isEmpty()) {\n throw new IllegalArgumentException("Invalid order");\n }\n}\n\nprivate BigDecimal calculateTotal(Order order) {\n return order.getItems().stream()\n .map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())))\n .reduce(BigDecimal.ZERO, BigDecimal::add);\n}\n\nRegra do escoteiro: deixe o acampamento mais limpo do que encontrou
\nCada vez que editar um arquivo, melhore-o: renomeie uma variável ruim, divida uma função longa. Isso evita a entropia do código.
\n\n<