Tecnologia / Artigos / O Guia Definitivo do Design de Software /
Dead code is dead

Cléber

![cross-and-crows.jpg](/files/146) *Photo by [Jacob Mejicanos](https://unsplash.com/@jacobmejicanos) on [Unsplash](https://unsplash.com/s/photos/dead)* --- A definição de "código morto" é razoavelmente ampla e parece variar bastante de pessoa para pessoa. Para o propósito deste artigo, considerarei como "código morto" o que cai em duas situações bem claras: código que nunca é executado e código transformado em comentários. # Código que nunca é executado Uma das coisas mais absurdas que já vi nessa vida de desenvolvedor foi um arquivo baixado do velho "PHP Classes" (yeap, eu trabalhei profissionalmente com PHP, também) que continha uma situação curiosa parecida com isso aqui: ```php if ($x ᐳ 10) { do_something(); } elseif ($x ᐸ= 10) { do_other_thing(); } else { schrodinger(); } ``` Caso não tenha ficado claro, a função `schrodinger` nunca será chamada, pois a dupla `if/elseif` já exaure todas as possilidades: (a) x é maior que 10 e (b) x é igual ou menor que 10. Logo, esse código deveria ser corrigido para ficar assim: ```php if ($x ᐳ 10) { do_something(); } else { do_other_thing(); } ``` Veja como a sensação de complexidade de um simples `if/else` é muito menor do que de um `if/elseif/else`! E como o código ficou consideravemente mais curto e, especialmente, **mais mentalmente são**. ## Confusão na cabeça de quem lê Se você está lendo um arquivo com código fonte e tentando entender do que se trata, provavelmente ficará mais feliz quanto mais curto ele for. Analisar 100 linhas de código, afinal, tem muito menos tendência de derreter um cérebro do que analisar 10.000 linhas de código, certo? E se, tentando entender o que está acontecendo (e mesmo código bem escrito pode não ser imediatamente claro, lembre-se), você se depara com duas ou três (ou cem!) funções que **parecem** se encaixar no contexto geral mas, estranhamente, não são chamadas por nenhuma outra ali por perto? É certo que isso te deixará curioso e você buscará pelo restante do código (com um simples `grep`, obviamente) para saber quem diabos chama aquelas funções -- para descobrir, no fim de tudo, que **ninguém** as chama. E agora? Essas funções são inúteis? Será que eu devo eliminá-las? E seu eu o fizer e o programa começar a apresentar problemas? Você pergunta para seus colegas e ninguém sabe responder. "Melhor deixar aí", alguém diz, e você deixa tudo lá, como uma herança malégna, uma maldição embrulhada de maneira dissimulada esperando o próximo programador a ser assombrado com todas essas dúvidas e dificuldades que você teve. E o mesmo ocorre com cada um e todo programador que passa por essa base de código infestada pelo mal... ## Contagem de linhas adulterada O código pode nunca ser executado, mas as linhas de código estão lá e serão contabilizadas por ferramentas especializadas (`cloc` ou `scc`, por exemplo). O que poderia ser "nós resolvemos esse problema com 500 linhas de código" passa a ser "nós resolvemos esse problema com 570 linhas de código" -- mais de 14% diferença e com proveito zero! Agora você não sabe dizer com muita certeza quão expressiva é a linguagem de programação que escolheu ou mesmo como essa solução se compara com outras similares. ## É compilado à toa Se sua linguagem é compilada, é provável que o código morto seja compilado junto com o código de verdade, adicionando mais tempo ao processo. E como vimos anteriormente, é fácil chegar em números expressivos de código inútil que tornará a compilação um pouco menos instantânea (ou um pouco mais miseravelmente demorada). E mesmo que sua linguagem faça *tree shaking*, cada pedaço de código inútil é uma decisão a mais nesse processo de escolha e análise. ## Mais nomes para conflitar Nem sempre conseguimos dar nomes absolutamente únicos e perfeitamente específicos e é bem possível que seu código inútil ocupe justamente alguns nomes que você gostaria de usar, mas agora terá que usar nomes menos ideais porque... sim. ## Pontos de coverage se perdendo Você é um desenvolvedor caprichoso e, desde que botou a mão no projeto, tem aumentado cada vez mais a cobertura de testes e, finalmente, conseguiu chegar a 100%! Ops, não. A 98%, porque você não escreveu testes para o código inútil, já que ele não é usado por ninguém e, portanto, você nunca chegará em 100% de cobertura. Taxa de cobertura, sabemos bem, é apenas mais um número e não consegue representar **qualidade**. Ele representa meramente quantidade. Mas, mesmo assim, há alguns projetos em que é possível alcançar excelência em ambos os aspectos e é evidente que chegar em 100% de cobertura é um marco interessante -- e do qual ninguém quer regredir. ## Testes escritos à toa Ou você decide **testar** o código inútil e gastou tempo, dinheiro e energia... com código inútil! Agora o processo de rodar os testes é mais demorado e aqueles preciosos minutos gratuitos que sua ferramenta de CI/CD lhe dá de bônus vão, aos poucos, escorrendo entre seus dedos. E pior: à toa. E ainda pode ser que algum fator inesperado faça justamente os testes do código morto falharem. Ele nunca era usado, afinal... # Código que virou comentário Apesar de não ter os efeitos negativos de contagem de linhas de código (não é compilado, não tira pontos de *coverage*, etc), código que virou comentário é tão pernicioso quanto código que nunca é executado. E pior: seu processo de remoção pode ser ainda mais difícil! ## Código não é repositório Comentar trechos de código porque "*vai que eu preciso depois!*" **elimina** a distinção entre comentários e "repositório". Se você descobriu que determinado trecho já não se faz necessáio, **elimine-o de uma vez** e confie que, se você quiser voltar atrás, todas aquelas boas práticas de `git` (ou seu sistema favorito) se mostrarão úteis e será fácil encontrar o que você precisa (porque suas mensagens de *commit* são boas) e restaurar o que for preciso (porque seus commits são atômicos). Puxando para cá o artigo anterior, **evite fazer saladas**. Código é código, repositório é repositório. Se você trouxer para dentro do código responsabilidades que são do repositório, tome logo uma decisão e não fique usando soluções meia-boca em locais arbitrários. ## Só faz sentido para você - e somente agora! O trecho de código que você deixou como comentário porque "*vai que eu preciso depois*" faz todo sentido na sua cabeça. Hoje. Amanhã você já nem achará tão importante. Semana que vem você já nem considerará aquilo válido. Daqui a um mês você estará se perguntando quem foi o imbecil que deixou aquele código morto lá. E se é assim para você, imagine para quem está lendo o código! E lembre-se: **nem todo leitor do seu código acompanhou o processo de desenvolvimento**. Algumas pessoas estão tão acostumadas com o processo de "pull/merge request" dos Github e Gitlab da vida que esquecem que o código é uma entidade à parte do próprio repositório e, especialmente, do histórico relacionado ao processo de desenvolvimento. O autor da alteração vê o *merge request* (o Gitlab chama de "Merge Request", o Github de "Pull Request", e eu acho que o Gitlab está certo) e, lendo aquele pequeno trecho com alterações, encapsulado numa entidade simples e com alta visibilidade, acredita que tudo o que acontece (que o código era assim, que agora é assado e que aquele trecho virou comentário por esse e por aquele motivo bizarros) torna-se óbvio e auto-explicativo. Mas não. Daqui a dois meses ninguém se lembrará do processo, mas alguém estará lendo seu código e se perguntando do que afinal se trataria aquele trecho "desativado". ## Adicionam mistério e suspense ao código Uma das características dos melhores programadores é que o código que escrevem é **claro**. É impressionante, realmente, ler código escrito por certas pessoas. As coisas parecem tão evidentes e simples! Logo, adicionar mistério e suspense **não é** algo desejável e provavelmente indica que você ainda está longe de ser um dos melhores. Considere o seguinte trecho de código: ```python # The code below is very important, since this constant # is key to finding the correct value for sigma: # the_constant = 10 the_constant = 2 ``` Ok. **Qual**, afinal, é o valor que é importante? 2 ou 10? Se 10 não é importante, por que ainda está lá? Será que o último desenvolvedor resolveu desobedecer A Antiga Voz do Comentário e alterar o valor importante e é por isso que a aplicação está com problemas? Ou será que o valor importante é o atual e posso apagar o comentário com o antigo? Ou será que na verdade tanto faz e esse valor nem é tão importante quanto o comentário diz? Pois é. Nunca saberemos com certeza. Boa sorte, aí, com tuas maldições da antiguidade. ## Absolutamente fogem do propósito real dos comentários Comentários tem dois e apenas dois propósitos: (1) documentar o uso das funções, classes, módulos e afins (coisa que chamamos, então, não de "comentário", mas de "documentação") e (2) ajudar os próximos desenvolvedores (ou você mesmo) a entender coisas que são realmente complexas e você sente que não tem jeito de explicar adequadamente somente com código. ```python def calculate_sigma(phi, zeta): """Calculate sigma value given a phi and a zeta parameters phi must be higher than 10, since below that there's no enough room for yada yada yada... """ iota = phi * MAX_ANGLE # Here we divide the value by 1 million so in the worst case # scenario we won't need "BigInt" and the code gets much # faster. It's not really necessary, but is very effective for # performance improvements. # (You can tweak this value, specially if running into other # architectures.) iota /= 1_000_000 ... ``` No código acima, que é completamente inventado e não faz sentido algum, temos dois tipos de "comentários": documentação e ajuda para o desenvolvedor. E ambos são perfeitamente corretos. Pode haver alguma discussão sobre a necessidade do longo comentário, mas não se pode dizer que isso vá realmente atrapalhar o entendimento do código. Sob certo ponto de vista, os comentários de ajuda fazem parte do código, também. Agora, se o que você está comentando não é nem documentação e nem ajuda para o desenvolvedor (pelo contrário: confunde e atrapalha), **simplesmente elimine o código morto**. # Resumo * Não deve ir para o repositório nenhum código que não seja absolutamente essencial. * Código morto está morto. Elimine-o.

Curti

35 visitantes curtiram esse Item.

Anterior: Evite saladas de frutas | Próximo: Teste tudo