Escrever pra máquina vs para humanos
Qualquer um consegue escrever um código que o Computador ou o V8 Engine consiga compilar. A máquina não liga para nomes como let x = 2;
O problema é que Lemos código 10 VEZES mais do que escrevemos! O verdadeiro teste de um desenvolvedor Pleno/Senior é escrever códigos tão óbvios e límpidos que os colegas de equipe não precisem desvendar um "quebra-cabeças" para dar manutenção.
Vamos dissecar agora os 8 Pilares Radicais de Clean Code adaptados para o ambiente Front-end contemporâneo.
O fim dos acrônimos adivinháveis
Segundo Bob Martin: "O nome de uma variável ou função deve nos dizer por que ela existe, o que faz e como é usada.".
Se um nome precisa de um comentário logo ao lado da declaração para você explicar o que de fato a mágica daquela Action faz, o nome já falhou miseravelmente em sua missão!
Nomes Significativos - Exemplo 1 💻
O que evitar? Letras avulsas, listas soltas e diminutivos criptografados.
O "encurtamento preguiçoso" faz o seu cérebro e o da equipe rodarem ciclos de processamento mental para mapear memórias (Ex: O que era o u mesmo?). Código lê-se feito jornal, deve ser óbvio, pesquisável num Cmd+F e claro.
Nomes Significativos - Exemplo 2 💻
O que evitar? Hardcodar algoritmos complexos baseados em Inteiros literais cegos.
Números mágicos escondem o Domínio do negócio. Se futuramente a permissão "Master" mudar para o banco de número 5, alguém teria de fazer uma busca perigosa por todos os "números 4" soltos pela codebase inteira e correndo risco de causar estragos.
Nomes Significativos - Exemplo 3 💻
O que evitar? Múltiplos parâmetros true/false mudando a função atirando para todo lado.
Aturar Flags booleanas soltas como argumento grita aos céus que a sua função faz mais de uma coisa dependendo do switch! Fora o inferno de leitura na invocação (Ninguém sabe o que o true significa sem usar Command+Click pra vasculhar a Type).
Pequenas, menores ainda e fazendo uma coisa.
A teoria define: "As funções devem ser pequenas. A segunda regra para funções é que elas devem ser menores ainda."
É insalubre rolar o Scroll do mouse por 400 linhas para ler o Método "ValidatePayment". Uma função deve ser um tijolo. Se ela está formatando moeda, validando erro, e enviando Toast Notification... ela virou um condomínio, não um tijolo!
Funções - Exemplo 1 💻
O que evitar? Alinhamentos de identação monstruosos encavalando sub-ifs seguidos.
Quanto mais fundo a indentação avança em colunas para a direita, gigantesca fica a carga cognitiva de manter a cadeia mental de negações de Ifs e Elses empilhados. O Early Return devolve o fluxo na cara do erro e despolui a linha principal!
Funções - Exemplo 2 💻
O que evitar? Funções exigindo 4, 5 ou 6 argumentos posicionais quebrando ordens.
A ordem posicional quebra fácil! Funções engessadas com muitos parâmetros destroem os testes e obrigam você a pular furos com undefined na assinatura se um dia o campo número 3 deixar de ser obrigatório na plataforma.
Funções - Exemplo 3 💻
O que evitar? Misturar parsing gráfico, chamadas lógicas e validações no mesmo bloco.
Se a sua lógica visual atrelou envios nativos de notificação da UI dentro de uma função de Matemática Tributária, testar isso requer instanciar O Sistema Inteiro Gráfico. Desacople! Funções utilitárias puras não manipulam DOM de surpresa!
Não comente o código ruim. Reescreva-o.
A teoria define: "Qualquer comentário é, no fundo, uma falha de expressão na linguagem.".
Comentários MENTEM. O código muda ao longo dos anos, e desenvolvedores quase nunca lembram de atualizar a linha verde inútil do comentário. No fim, eles desacompanham a lógica e geram extrema confusão.
Comentários - Exemplo 1 💻
O que evitar? Escrever parágrafos para explicar o que um IF horroroso significa.
Ao invés de passar 2 minutos escrevendo um poema de Shakespeare detalhando o quanto de lixo matemático aquela condição faz... Basta extrair a verificação para uma constante nomeada! O leitor entenderá o IF intuitivamente de graça.
Comentários - Exemplo 2 💻
O que evitar? Deixar Blocos imensos "Comentados/Anulados" com medo de perder.
O "Deixa aí que posso precisar amanhã" vai acumulando poeira nos repositórios criando um medo visual brutal em recém-contratados ("Isso aqui tá comentado mas é importante? Eu deleto?"). É puro Lixo! Controle de versão (Git) existe 100% pra isso.
Comentários - Exemplo 3 💻
O que evitar? Gastar linhas coloridas descrevendo literalmente o óbvio visual.
Escrever linhas mortas como // Instancia usuario em cima de um nítido new User() é poluição literária ruidosa inútil. Comentários Sadios existem única e exclusivamente para Explicar Motivações Ocultas (Ex: Razões de Negócio Exóticas ou Correções de Bug do Browser).
A organização limpa da vida dos dados
A teoria define: "O código deve ser formatado como uma reportagem confiável que instigue leitura limpa de dependências e estados".
Programadores inexperientes deixam rastros de variáveis flutuantes let serem assombradas por infinitas mutações lá por baixo da tela inteira, gerando Side-Effects caóticos. Preze por arquivos blindados em "Exports Limpos" e "Mutabilidade Zero"!
Estrutura Front - Exemplo 1 💻
O que evitar? Declarar estados fantasmas perdidos na montanha que sofrem Reassigneds.
Quando você adota a diretriz sagrada de "Prefer Const Over Let", elimina bugs terríveis de colaterais, impedindo que partes do HTML/Componente recebam a string corrompida por acidente lá do final da leitura. Valores devem fluir e imobilizar!
Estrutura Front - Exemplo 2 💻
O que evitar? Poluir a parte superior da classe com Diretórios caçados em ../../../..
Estrutura limpa de importação é saúde mental. Path aliases blindados e Barrels reduzem 15 mil linhas de código em Refatorações grandes de realocações de pastas. O import mergulha na semântica real (Um módulo raiz) invés da hierarquia estúpida do seu Disco Local.
Estrutura Front - Exemplo 3 💻
O que evitar? Deixar Types, Interfaces, Constantes e Classes tudo no Component.
Deixar Types vazarem dentro de classes causa Acoplamentos Cíclicos circulares (Módulo A chamando B que importa O Type dentro do arquivo de Classe de A)! Ao isolar as Contratações (Interfaces .models) em arquivos secos puros, o TS respira maravilhosamente bem!
A raiz dos Bugs: Ifs enjaulados sujos.
A teoria define: "O cérebro tem extrema dificuldade em parsear cadeias duplas negativas ou engarrafar lógicas polinomiais de Switches em métodos focados.".
A complexidade Ciclomática (números pesados de Switches, whiles, ifs enfiados juntos) é o que mais envelhece o código legado. Domar as Condicionais convertendo lógicas bizarras em Mapas Diccionários fluidos é o supra-sumo do Clean-Code Dinâmico!
Condicionais e Lógica - Exemplo 1 💻
O que evitar? Obrigar o cérebro a inverter significados toda hora.
Na Programação Dinâmica, um Boolean Negativo acompanhado de um operador NOT (!) soa torturante (se 'Não for Inválido' então faça). Escrever funções puramente positivas garantem a harmonia da conversação com a leitura e diminui bugs bestiais por deslizes de acentos.
Condicionais e Lógica - Exemplo 2 💻
O que evitar? Jogar expressões matemáticas abertas no meio da execução.
Ao espalhar "ifs pelados gigantes" o leitor gasta 10 segundos entendendo os andares (&&) para no final não saber o que aquele combo realmente significa para os Negócios da Empresa. Encapsular a conta gigante numa Constante nomeada gera fluidez imediata à abstração e brilha forte!
Condicionais e Lógica - Exemplo 3 💻
O que evitar? Ficar repetindo Switches Case nas Views mudando ícones de Types.
O Switch-Case suja verticais brutais no Typescript. Substituí-los por Mapas de Chaves (Dictionary/Record Objects) isola as possibilidades Extensíveis do Sistema sem entupir funções de controles complexos, garantindo 100% de flexibilidade caso chaves venham do Back-End dinamicamente!
O pesadelo do Ctrl+C Ctrl+V guiado a pressa.
A teoria define: "Cada pedaço de conhecimento ou lógica de negócios deve ter uma, e apenas uma, representação autoritativa no sistema inteiro.".
O Programador Pragmatico abomina escrever a mesma equação de CSS ou TypeScript duas vezes. Se você precisa aplicar o mesmo efeito de UI em 3 telas copiando as Divs em todas elas... você falhou em abstrair componentes. O retrabalho será letal!
DRY / Repetição - Exemplo 1 💻
O que evitar? Escrever a mesma Box de Notificação solta crua em cada Action File.
Se amanhã o Marketing decidir que a borda do Alert Box não é mais quadrada, é arredondada, e a cor mudou... Pagar desenvolvedores pra ficarem dando Localizar/Substituir em 80 telas do projeto buscando onde as divs estavam escondidas é um completo rasgo de dinheiro corporativo.
DRY / Repetição - Exemplo 2 💻
O que evitar? Atirar pedaços de textos soltos de chaves de API/Config pelo Type.
Erros de digitação em Strings são impossíveis de serem "pegos" pelo compilador do Typescript. Ele confia na sua digitação! Um enum ou Objeto Constante amarra o Linter que gritará Alto na IDE se você chamar uma chave inexistente preservando o DRY.
DRY / Repetição - Exemplo 3 💻
O que evitar? Criar arrays "let" e ficar metendo push via "for" sem usar Funcionais.
Sintaxe baseada em length e i++ expõe a lógica interna desnecessariamente e afunda sua credibilidade para Seniors reescrevendo implementações pesadas de Loops For. Aproveite as High-Order Functions (HOF), filtre, altere e mapeie direto com o JS limpo!
A arte de não ser pego de surpresa na madrugada.
A teoria define: "Lidar com erros é só uma das suas preocupações, mas se atrapalhar o fluxo limpo e o entendimento, seu código está errado.".
Você não é pago apenas para escrever o "Caminho Feliz". A verdadeira robustez do Software nasce de como a Arquitetura Frontend prevê, engole e repõe a tela quando o Back-end soltar um 500 Internal Server Error. Retornar nulos silenciosos destrói debuggings futuros!
Tratamento Erros - Exemplo 1 💻
O que evitar? Jogar Erros pra debaixo do tapete que quebram o código sorrateiramente.
O Catch oco é o maior calcanhar de Aquiles do desenvolvimento Jr. O cliente reclamará que o botão roxo não executa nada, a QA vai abrir Bug, E você não achará erro absolutamente NENHUM em lugar algum no navegador. O Console e os Logs Varreram o crime!
Tratamento Erros - Exemplo 2 💻
O que evitar? Retornar falsos "indefinidos" ao invés de jogar e propagar a dor real.
O problema em inventar status null é que o código que chamou a Função pai terá de fazer os famosos e infinitos if(user != null) para checar, e muitas vezes esquecerá, gerando a tela branca (Crash V8). Lançar Errors garante paradas forçadas ou bloqueios!
Tratamento Erros - Exemplo 3 💻
O que evitar? Sub-promises seguidos e checadores engatados manualmente de redes.
Aninhar a arquitetura de retornos Callback gerava dívida Ciclomática monstruosa no JavaScript da década anterior. Acoplar sub-catchers torna a trilha de rede pesada. Usar `Async/Await` isola o Caminho Feliz enquanto o Bottom Level captura globalmente falhas de ambos os servidores!
A imutabilidade no fluxo de informações
A teoria define: "A diferença entre Dados e Objetos é que Dados operam à mostra, enquanto Objetos operam blindando seus comportamentos internos expostos".
Quando um componente Frontend emite ou injeta Objetos brutos Javascript passando-os por "referência física", o dano interno de esbarrar sem querer em Propriedades filhas altera Globalmente até as Lists mães fora do escopo.
Fluxos de Dados - Exemplo 1 💻
O que evitar? Crer cegamente que o Objeto que veio do JSON externo desceu íntegro.
Muitos Seniors gastavam horas fazendo: if(user != null && user.profile != null) para checar escopos. Assumir que redes são íntegras em 100% quebra qualquer View de usuários. O ?. (Optional Chaining) é a espada sagrada contra Erros de renderização crua no DOM.
Fluxos de Dados - Exemplo 2 💻
O que evitar? Reescrever/Assinalar Campos de Argumentos Embutidos Recebidos pelo Pai.
Argumentos em JS no modo primitivo Objects fluem por RefPoint (Ponteiros de Memória Físicos). Quando você sobrescreve `user.x = y` sem clonar antes, a alteração "Vaza" de volta para todas as listas que renderizaram e deram bind daquele User antes, corrompendo a Session state inteira do Angular Data.
Fluxos de Dados - Exemplo 3 💻
O que evitar? Jogar milhares de chaves aleatórias e cruas aos Ventos para Outputs Components.
Data Clumps ocorrem quando um grupo de Primitivos Data sempre transitam misteriosamente juntos pelas assinaturas de métodos (ruído excessivo). Eles naturalmente pertencem ao mesmo Escopo Conceitual. Você precisa agrupá-los em 1 único model "UserDto". Despejar tudo como Inputs soltos gera dor.
Quando deixamos o código de legado assustar o time inteiro de apertar Commit achando que o servidor vai desabar...
Significa que a Régua do Clean Code não existiu. Não proteja as coisas erradas da sua equipe com remendos. Reescreva com Nomes Semânticos, Funções Puras Menores, Abstrações Positivas e Imutabilidade Sagrada!
O Segredo: Código limpo é como ler uma piada excelente. Não precisa de ninguém ali do seu lado para tentar explicá-la no fim da linha!.
Dessas Regras Pragmáticas dissecadas nos 💻 Códigos...
Qual Regra Oculta Mais Incomoda você e faz os Seniors baterem nas Paredes na sua Empresa?
Solta a voz nos comentários! 👇