Alguém poderia explicar as vantagens de excluir (ou manter) código não utilizado?

102

Já ouvi muitas vezes que o código não utilizado deve ser excluído do projeto. No entanto, não está claro para mim "por quê?".

Meus pontos por não excluir que são:

  • O código já está escrito e os esforços são feitos
  • O código pode ser testado em ambiente sintético e real
  • Se bem organizado (agrupado, pacote separado, fracamente acoplado etc), não perturba você na análise geral do código ou refatoração
  • O código pode ser usado no futuro
  • Quando excluído, o autor pode se sentir desconfortável

Alguém poderia explicar as vantagens de excluir (ou manter) código não utilizado?

Alex Turbin
fonte
16
O código comentado também não deve pertencer a uma base de código.
leppie
27
Porque temos controle de versão. Se precisarmos nos referir a versões antigas do código, podemos simplesmente revisar o histórico.
armandino
1
A propósito, referir-se ao controle de versão pode ser difícil, quando o projeto é grande e alguns arquivos têm> 200 revisões
Alex Turbin
22
@AlexStamper, se suas ferramentas não permitem que você examine facilmente as revisões anteriores de seu código, a solução seria obter ferramentas melhores, não adicionar ruído ao seu código-fonte.
utnapistim
1
A Engenharia de Software tem uma pergunta muito semelhante .
davidvandebunte

Respostas:

180

Aqui estão alguns motivos pelos quais o código não utilizado deve ser removido:

  • Para qualquer um que esteja trabalhando em um projeto, eles não apenas precisam entender o código de trabalho, mas também o material não utilizado. Isso é tempo perdido e cria confusão.

  • Existe o perigo de que em algum momento alguém faça uma alteração que inadvertidamente envolva o código 'dormente' e pode introduzir bugs. Eu sei que isso aconteceu em projetos em que trabalhei.

  • A manutenção de qualquer código é um fardo administrativo. Ao preservar o código redundante antigo, essa carga é aumentada. Por exemplo, mesclar alterações no branch principal se torna mais difícil porque há mais código para trabalhar e mais possibilidade de cometer um erro.

  • O que acontece com o tempo é que mais e mais códigos antigos não utilizados são adicionados à base de código. Isso aumenta a confusão, mal-entendido potencial e sobrecarga administrativa.

  • As chances de que o código não utilizado seja usado novamente são muito improváveis. Com o tempo essa possibilidade de reutilização diminui. Se o código deve ser removido e é considerado importante o suficiente, ele pode ser ramificado e documentado.

  • Quaisquer sentimentos pessoais que um codificador possa ter sobre o código no qual ele pode ter trabalhado muito é compreensível. Mas parte de ser profissional exige que esses pensamentos sejam colocados de lado para o bem melhor. O tempo não representa ninguém e não há lugar para preservar o código histórico em uma base de código de trabalho.

Suspeito
fonte
26
Eu tive muito medo de mim recentemente devido a olhar para um código não usado (e não perceber que ele não estava sendo usado). O código não utilizado deve ser eliminado da existência!
leppie
1
bons pontos, obrigado. Meus colegas declararam vários deles também
Alex Turbin,
Excelente resposta. Gostaria de fazer referência a argumentos como esses em minha dissertação de mestrado, mas não consigo encontrar uma fonte apropriada (livro, artigo, etc). Você tem alguma pista?
Jonas Winkler
3
Eu estaria muito interessado em suas razões para o voto negativo agora.
suspeito
1
Mais um ponto: se o código antigo for necessário novamente, a maioria dos projetos hoje em dia usa um SCM e o código pode ser extraído dele novamente (às vezes com alguma pesquisa, é verdade, mas como claramente apontado na resposta, a probabilidade de código não usado ser necessário diminui novamente com o aumento da idade).
Corte em
31

@suspectus fez um excelente trabalho ao apresentar as razões para a exclusão do código; Eu gostaria de abordar seus marcadores individuais para manter o código.

  • O código já está escrito e os esforços são feitos

Mas se o código já escrito não estiver em uso, isso terá custo sem valor (futuro). É um esforço investido em vão, e preservar o produto não utilizado desses esforços não valida esses esforços. Mantemos o código porque ele é útil, agora, não como uma espécie de memorial aos esforços dos autores.

  • O código pode ser testado em ambiente sintético e real

Sinto muito, não sei o que você quer dizer com isso.

  • Se bem organizado (agrupado, pacote separado, fracamente acoplado etc), não perturba você na análise geral do código ou refatoração

Se ele existir na base do código, não importa o quão bem organizado, ele contribui para a carga de manutenção e compreensão. É verdade que pode ser organizado de forma a ser menos incômodo, mas, se sumir, não é nenhum peso.

  • O código pode ser usado no futuro

Na escola Agile, dizemos YAGNI : Você não vai precisar disso. Sim, você pode ter um uso para isso no futuro, mas não podemos saber o suficiente hoje sobre as necessidades de amanhã para sermos capazes de prever isso com qualquer tipo de confiabilidade. Pensar o contrário é arrogância tendendo à arrogância. O que podemos saber sobre o amanhã é: queremos que nossa base de código seja fácil de modificar e o código não utilizado prejudica essa característica.

  • Quando excluído, o autor pode se sentir desconfortável

O autor deve superar isso. Todos nós escrevemos coisas que acabaram não sendo úteis - muito melhor ser capaz de apontar para um corpo de código que está todo sendo usado (porque o fragmento não utilizado foi excluído) do que um corpo de código do qual você pode falar alguns métodos, "e aquele está realmente em uso!"

Carl Manaster
fonte
17

Não é difícil pegar alguns códigos e descobrir a intenção, mas agora você precisa descobrir quais partes não estão em uso?

Kenny
fonte
14

O código já está escrito e os esforços são feitos

Também é desnecessário. Se você não o usa para nada, é (por definição) inútil, independentemente do que faça ou de quanto esforço foi gasto nele.

O código pode ser testado em ambiente sintético e real

Se for inútil, ainda é inútil, mesmo se você tiver testes nele. Se o código for inútil, os testes para ele também serão inúteis (portanto, manter o código comentado ali cria ambigüidade - você mantém os testes? Se você tinha o código do cliente do código comentado, você comenta o código do cliente também? )

Se bem organizado (agrupado, pacote separado, fracamente acoplado etc), não perturba você na análise geral do código ou refatoração

Não tão. Todas as suas ferramentas (controle de origem, análise estática, extrator de documentação, compilador, etc) irão rodar mais devagar, porque precisam processar mais dados (e uma parte maior ou menor desses dados é ruído).

Por outro lado, se o código não estiver bem organizado, ele bagunçará a análise estática, a refatoração e quaisquer outros.

Você está introduzindo ruído na entrada de suas ferramentas e esperando que elas lidem corretamente com ele.

E se a sua ferramenta de análise estática computar uma proporção de comentários / código? Você acabou de bagunçar, com algo que era relevante até ontem (ou sempre que o código era comentado).

O mais relevante de tudo é que os blocos de código comentados apresentam atrasos na compreensão do código para manutenção e desenvolvimento posterior e esses atrasos quase sempre custam muito. Pergunte a si mesmo: Se você precisa entender a implementação de uma função, o que você prefere ver? duas linhas de código claro ou duas linhas de código e outras vinte e seis de comentários que não são mais reais?

O código pode ser usado no futuro

Se for, você o encontrará no SCM de sua equipe.

Se você usar um SCM competente e confiar nele para manter o código morto (em vez de bagunçar a fonte), você deve ver não apenas quem excluiu esse código (autor do commit), mas por qual motivo (mensagem de commit), e quais outros mudanças foram feitas junto com ele (o resto das diferenças para aquele commit).

Quando excluído, o autor pode se sentir desconfortável

Assim?

Você é (eu presumo) uma equipe inteira de desenvolvedores que é paga para fazer o melhor software que você conhece, não "o melhor software que você conhece, sem ferir os sentimentos de X".

É uma parte da programação que a maior parte do código escrito será descartada; por exemplo, Joel Spolsky disse em algum momento que, para sua empresa, aproximadamente 2% do código escrito é produzido.

Se você priorizar o ego dos desenvolvedores sobre a qualidade da base do código, você sacrificará a qualidade do seu produto, por ... o que exatamente? Preservando a imaturidade de seus colegas desenvolvedores? Protegendo as expectativas irrealistas de seus colegas?

Edit: Eu vi um motivo válido para deixar o código comentado na fonte, e é um caso muito específico: quando o código é escrito de uma forma estranha / não intuitiva e a maneira limpa de reescrevê-lo não trabalhar por uma razão muito sutil. Isso também deve ser aplicado somente após uma tentativa repetida de corrigir o problema e sempre que a tentativa reintroduzir o mesmo defeito. Nesse caso, você deve adicionar o código intuitivo comentado como um comentário e explicar por que ele não funciona (para que futuros desenvolvedores não tentem a mesma mudança novamente):

// note by <author>: the X parameter here should normally
// be a reference:
// void teleport(dinosaur& X);
// but that would require that we raise another dinosaur and
// kill it every twelve hours
// as such, the parameter is passed by value
void teleport(dinosaur X);
utnapistim
fonte
10

O código morto está poluindo seu código

O código morto diminui a compreensão e a legibilidade.

Os melhores códigos são sempre reutilizados, e se você tiver códigos mortos, isso reduz a capacidade de reutilização

Somos movidos por uma abordagem modular de codificação, em que projetamos códigos para interação com nossos colegas programadores, não para uma máquina. Devemos colocar o máximo de energia para facilitar a compreensão do nosso código. A máquina vai ficar bem de qualquer maneira.

Código morto ou comentado é como sinais de trilha falsos que apenas confundem as pessoas, portanto, evite-o a todo custo.

Jimmy
fonte
10
  • Medo . Isso faz com que a equipe se preocupe mais e produza menos. A quantidade de medo aumenta exponencialmente quando mais código morto é introduzido. "Não sabemos se essa broca é usada, por isso não ousamos removê-la ou tocá-la."
  • Mudanças radicais . Se algo que precisa ser alterado em qualquer lugar do sistema também existe no código morto, você o altera? É muito difícil saber se definitivamente não é usado em algum lugar, então é sempre um risco. E mesmo que não quebrasse nada, o código morto funcionaria se fosse retomado para uso após essa alteração?

    Ao lidar com uma mudança radical, os desenvolvedores também terão que verificar cada lugar que contém o código e, no caso de código morto, isso é redundante. E verificá-los leva mais tempo quando o código está morto, pois é difícil verificar se ele não é usado em lugar nenhum.

  • Carga mental . Toda vez que você precisa pensar se algo é usado ou se deve fazer algo com o código morto, é preciso um pouco do poder do seu cérebro.
  • Perseguições de ganso selvagem . "Preciso de um exemplo de como usar o Foobar. Está nesses lugares da base de código. Vou verificar a primeira ocorrência e descobrir onde está na IU. Hmm ... Não consigo encontrar em lugar nenhum."
  • Relatórios inflados (por exemplo, quantas linhas de código, classes, rotinas, mudanças). Distorce a visibilidade do projeto e as decisões sobre quais partes da base de código devem ser trabalhadas e as estimativas de projetos futuros.
  • Confiança enfraquecida na base de código . Isso pode resultar em mais tempo gasto em tarefas redundantes e interrompe o fluxo de uso da base de código. Os desenvolvedores podem ter que verificar com extremo cuidado se tudo o que usam funcionará da maneira que acham que deveria.

É extremamente valioso se você souber que uma parte da base de código não é usada, porque então você pode removê-la. Se você deixá-lo ficar, no futuro pode ser difícil ou quase impossível ter certeza de que ele realmente não é usado. Por exemplo, algumas das coisas que usam código de maneiras surpreendentes: reflexão, rotinas de chamada dinâmica concatenadas de strings, eval, magia de estrutura .

No entanto, se houver uma grande probabilidade de que o código seja usado no futuro, é mais fácil adicionar se estiver ali junto com o outro código, em vez de no sistema de controle de versão. Você pode não se lembrar de nenhuma palavra do código depois de um tempo, então pode ser muito difícil encontrar o código nas entranhas do VCS. Mas eu deixei código morto existir apenas raramente e mesmo assim eu comentaria o código.

Heikki Naski
fonte
4
  • O código não utilizado é um espaço de pesquisa maior para você ler e qualquer outra coisa que geralmente verifica seu código. Por exemplo, um compilador, IDE, localizar no arquivo, depuração, análise estática, mais para revisar, inclusão de arquivo, check-out do VCS, etc. Isso retarda esses processos e adiciona ruído significativo.
  • O código não utilizado nem sempre é um código morto. Ele pode ser executado em certas circunstâncias. Isso pode não apenas oferecer um vetor para bugs e problemas de desempenho, mas também pode ser uma preocupação de segurança. Com relação ao desempenho, isso pode se expressar de maneiras inesperadas, como downloads maiores.
  • Código não utilizado gera código não utilizado. Se você excluir uma chamada de função e, em seguida, pesquisar os usos dessa função para ver se ainda é necessária, você poderá ver uma correspondência do código anterior não utilizado e assumir que pode mantê-la. Quanto mais código não usado você tiver, mais saltos haverá para determinar se o código não está sendo usado.
  • O código não utilizado ainda muitas vezes acaba tendo que ser mantido. Vamos dizer que A e B dependem de C. Desses, B não é usado. Você altera C e B não compilará porque removeu um membro de uma estrutura em C que B exigia, agora você precisa corrigir B ​​ou removê-lo ativamente da compilação. Você deveria simplesmente tê-lo removido.

Esta lista pode parecer simples, mas cada um deles se manifesta de centenas de maneiras diferentes, adicionando arrasto que sinergia em todo o processo de desenvolvimento. A ineficiência muitas vezes pode ser comprovada ou demonstrada de maneira direta e matemática.

Em resposta aos seus pontos ...

  • O código já está escrito e os esforços são feitos

Mas muitas vezes deve ser mantido. Ele também aparecerá ainda em itens como localizar no arquivo.

  • O código pode ser testado em ambiente sintético e real

Não tenho certeza do que você quer dizer com este. Acho que é igual ao anterior. Você quer dizer que o código já foi testado e limpá-lo pode significar que ele precisa de um novo teste. Esse é um custo que geralmente vale a pena porque compensa 90% do tempo e para evitar que deveria ter sido limpo antes de entrar em produção. Quase todo código tem duas iterações, faça funcionar, faça-o limpo. O motivo de ter que ser testado duas vezes é porque alguém pulou a última etapa. Se o seu código também for muito caro para revisar a diferença, teste (o que provavelmente será se estiver confuso com muito código não utilizado), etc, então esse é outro problema.

  • Se bem organizado (agrupado, pacote separado, fracamente acoplado etc), não perturba você na análise geral do código ou refatoração

Seu código deve ser assim de qualquer maneira, mas isso apenas atenua o problema moderadamente. É o argumento mais estranho ouvir que algo deveria ser organizado, mas impuro. É normal tentar manter o código modular e reduzir as dependências, mas você também quer código reutilizável e, se todos os seus módulos forem uma ilha, é provável que você não tenha sido DRY. Você também pode acabar fazendo uma dissociação excessiva que não faz nada além de mitigar o problema de código confuso não utilizado.

  • O código pode ser usado no futuro

Muitas pessoas valorizam o código escrito. Se não for usado agora, é peso morto e, na realidade, quando você segue por esse caminho, muitas vezes apenas uma fração do código não usado se torna código usado. Com toda a probabilidade, o código não utilizado provavelmente não será um código utilizável ou usado. O código mais provável de ser reutilizado é o código usado que está fazendo algo.

O que é pior é que o código não utilizado não tem um propósito. Quando alguém chega e tem que mudar algo que acaba impactando o código não usado, eles vão ficar perplexos tentando descobrir o que esse código não usado sem propósito precisa fazer.

É fácil para as pessoas se sentirem assim ao começar, pois o código exige muito esforço. Uma vez fluente e acostumado com ele, o código se torna como andar de bicicleta. Você descobrirá que o custo de escrever um código como esse diminui o custo de mantê-lo sobe.

  • Quando excluído, o autor pode se sentir desconfortável

Esse é o problema do autor. Por um lado, é egoísta deixar um monte de código não utilizado para que outros tenham que lidar. Por outro lado, se um autor coloca seus sentimentos sobre a qualidade do código, ele provavelmente não deveria estar codificando. Você segue a estrada com isso de que você não pode consertar o código deles quando está quebrado porque isso vai ferir seus sentimentos. Não é um bom sinal se alguém se apega ao código simplesmente porque é dela, e não porque é bom. Um autor deve se sentir feliz com a limpeza de seu código. É como se alguém pegasse o lixo para você e jogasse na lixeira.

Eu ficaria nas nuvens se alguém fizesse isso por mim. O que pode tornar mais fácil superar esses sentimentos é, em vez de esperar que outra pessoa faça isso, tente fazer você mesmo. Continue reescrevendo iterativamente uma parte do código que você fez, tornando-o melhor, mova-se de forma concisa, com menos excesso e mais flexível, mas com menos código a cada vez. Tente não se sentir bem com a quantidade de código, mas com o quanto você pode conseguir com o mínimo de código. Isso é difícil para subir de nível e, uma vez que você fizer isso, todo o seu código sairá em um bom nível seguinte, então não precisará ser nivelado com tanta frequência.

jgmjgm
fonte
3

Em primeiro lugar, você deve sempre usar uma ferramenta de controle de origem para gerenciar seus projetos e, portanto, remover o código não utilizado é uma boa prática, pois você sempre pode voltar usando o controle de origem para obter o código removido. Para mim, o motivo de remover o código não utilizado é que apenas a pessoa que sabe que o código não é usado sabe sobre ele, alguém da equipe vai encontrar esse código e tentar descobrir o que ele faz e como ele se encaixa em todo o aplicativo e ficará desapontado depois de tanto esforço que o código não será usado :)

Ankur
fonte
3

Esta discussão já existe há vários anos, mas acabei de encontrá-la ...

Uma coisa que não vi mencionado é o trabalho que deve ser feito para remover o código não utilizado. Em muitos casos, o tempo e o esforço para remover o código não utilizado não são triviais por natureza, além de normalmente haver custos adicionais para testar e documentar o sistema refatorado. Só mais uma coisa a se considerar no processo de decisão.

RonE
fonte
2

Eu acho que você pode ter dois casos: - código do aplicativo: se não for usado, talvez não tenha sido testado e mantido ao longo do tempo, talvez você possa mudar para um "repositório de código interno" - código API: se você está escrevendo uma biblioteca, IMHO é uma escolha melhor para mantê-lo, mas dentro de seu processo de desenvolvimento ativo

Antonello Pasella
fonte
2

Tem certeza de que o código não é usado?

Não é suficiente verificar se o código ainda está compilando. Em C ++, se você remover um método "não utilizado" implicitamente definido como operator=se não fosse obter um erro do compilador, a classe apenas começará a usar silenciosamente uma implementação padrão (potencialmente incorreta). Em Java ou C #, o código pode ser usado por meio de reflexão. Em linguagens orientadas a objetos, a herança pode desempenhar um papel (a classe base agora pode ser chamada). Em quase todos os idiomas, outra função sobrecarregada pode ter assumido o controle.

Verifique a idade do código no controle de versão, não apenas se ele não está sendo usado. Eu vi um código que parecia não usado, mas tinha acabado de ser confirmado e foi na verdade a primeira etapa no projeto de outro desenvolvedor.

Remova agressivamente o código não utilizado

Você paga para manter o código:

  • Consertando compilações quebradas (tempo de engenharia). Recentemente, tivemos uma complicada cadeia de #includemudanças, introduzindo uma nova sobrecarga no código não utilizado, levando a uma dor de cabeça de tamanho razoável para cada engenheiro em uma equipe de dezenas de desenvolvedores.
  • Em recursos de máquina em testes (supondo que você tenha compilações contínuas de autoteste). Minha equipe recentemente analisou todos os nossos testes mais lentos, e muitos deles foram sobre códigos não utilizados de outra forma. Os engenheiros que executam testes localmente ou como parte da integração contínua estão aguardando testes sobre o código não utilizado.
  • Em termos de legibilidade (tempo de engenharia novamente). Seus arquivos de cabeçalho representam uma API. Se eles incluem funções que ninguém gostaria de usar, mas todos têm que ler, a curva de aprendizado do seu código é muito mais difícil.
  • Em pesquisas de código (tempo de engenharia novamente). Você limparia sua casa, seu disco rígido ou o Google Drive? Quanto mais você pesquisa um domínio, mais importante é que ele tenha conteúdo relevante para evitar falsos positivos (ou você usa uma pesquisa mais sofisticada como um mecanismo de pesquisa na web).

Eu diria que basicamente todo o código que o desenvolvedor médio escreve deixa de ser usado em um horizonte de cinco anos, então essa atividade nunca para. Não deixe isso ser você; escreva apenas código de alta qualidade e absolutamente necessário.

davidvandebunte
fonte