Devo reutilizar variáveis?

54

Devo reutilizar variáveis?

Eu sei que muitas práticas recomendadas dizem que você não deve fazer isso, no entanto, mais tarde, quando um desenvolvedor diferente está depurando o código e tem 3 variáveis parecidas e a única diferença é que elas são criadas em locais diferentes no código, ele pode estar confuso. O teste de unidade é um ótimo exemplo disso.

No entanto, sei que sabem que as melhores práticas estão na maioria das vezes contra isso. Por exemplo, eles dizem para não "substituir" os parâmetros do método.

As melhores práticas são contra a anulação das variáveis anteriores (em Java há o Sonar que dá um aviso quando você atribui null à variável, que não é necessário fazer isso para chamar o coletor de lixo desde o Java 6. Você não pode sempre controlar quais avisos estão desativados; na maioria das vezes, o padrão é ativado.)

    
por IAdapter 21.10.2011 / 10:08
fonte

12 respostas

124

Seu problema aparece apenas quando seus métodos são longos e estão executando várias tarefas em uma sequência. Isso torna o código mais difícil de entender (e, portanto, manter) per se. A reutilização de variáveis adiciona, além disso, um elemento extra de risco, tornando o código ainda mais difícil de seguir e mais propenso a erros.

A melhor prática do IMO é usar métodos curtos que façam uma única coisa, eliminando todo o problema.

    
por 21.10.2011 / 10:10
fonte
47

A reutilização variável em um método é um sinal strong de que você deve refatorar / dividi-lo.

Então minha resposta seria que você não deveria reutilizá-los, porque se você fizer isso, seria muito mais difícil refatorá-lo mais tarde.

    
por 21.10.2011 / 10:15
fonte
18

Depende.

Algumas variáveis podem ser criadas exatamente com o propósito de manter um determinado tipo de dado, que pode mudar durante a execução de uma função. Códigos de retorno vêm à mente aqui, por exemplo:

void my_function() {
    HRESULT errorcode;
    errorcode = ::SomeWindowsApiFunction();
    if (FAILED(errorcode)) { /* handle error */ }
    errorcode = ::AnotherWindowsApiFunction();
    if (FAILED(errorcode)) { /* handle error */ }
}

O nome da variável deixa bem claro o que esta variável deve armazenar. Acho que outros casos como esse são possíveis, em que uma variável é conceitualmente um contêiner que é usado logicamente por instâncias diferentes de coisas muito semelhantes durante o curso de uma função.

Em geral, no entanto, isso deve ser feito apenas em circunstâncias em que fique absolutamente claro para os possíveis leitores do código. Em nenhum caso, exceto talvez a otimização extrema sem considerar a legibilidade do código, uma variável deve ser reutilizada apenas porque o tipo é adequado.

Tudo isso basicamente segue de boas práticas na nomenclatura de variáveis. Os nomes devem falar por si mesmos. Se é difícil colocar o propósito exato para todas as reutilizações em um nome curto, é melhor usar apenas variáveis distintas.

    
por 21.10.2011 / 13:39
fonte
15

A maior razão pela qual não reutilizo variáveis (especialmente em testes de unidade) é porque introduz um caminho de código desnecessário, um que é difícil de testar e depurar. Um bom teste de unidade deve ser independente de outros testes e quando você reutiliza a variável de nível de classe (instância) em um dispositivo de teste de unidade, você deve garantir seu estado antes de cada teste. Um bom teste unitário também isola os defeitos, portanto, em teoria, cada caso de teste (método) deve apenas declarar 1 comportamento para o sistema sob teste. Se seus métodos de teste são escritos assim, raramente há necessidade ou benefício de reutilizar uma variável de nível de método. Por último, em linguagens que suportam fechamentos e processamento assíncrono, é realmente difícil raciocinar sobre o que está acontecendo se você estiver reutilizando variáveis em um método.

    
por 21.10.2011 / 10:52
fonte
13

Você deve usar variáveis diferentes. Se você está preocupado com o fato de seu colega ficar confuso, dê a ele nomes que claramente cubram seus papéis.
A reutilização de variáveis é uma provável fonte de confusão no futuro; melhor para limpá-lo agora.
Em alguns casos, o mesmo nome de variável pode ser reutilizado; por exemplo, i em um loop de contagem simples. Nestes casos, você deve certificar-se de que as variáveis estão em seu próprio escopo.

EDIT: A reutilização de variáveis é, às vezes, um sinal de que o Princípio da Responsabilidade Única é violado. Verifique se a variável reutilizada é usada na mesma função. Se for, ele pode não ser reutilizado (embora ainda seja preferível ter duas variáveis diferentes, para restringir o escopo das referidas variáveis). Se for usado em diferentes funções, você terá uma violação de SRP em mãos.

    
por 21.10.2011 / 10:13
fonte
4

Existe uma situação na qual você pode querer reutilizar uma variável, independentemente do ótimo conselho dado por outras respostas: quando seu compilador precisa de ajuda.

Em alguns casos, seu compilador pode não ser inteligente o bastante para perceber que uma determinada variável alocada para registradores não está mais sendo usada pela próxima parte do código. Portanto, ele não irá reutilizar esse registro teoricamente livre para as próximas variáveis, e o código gerado pode ser sub-ótimo.

Note que eu não sei de nenhum compilador mainstream atual que falhe em pegar esta situação corretamente, então nunca, nunca, nunca faça isso a menos que você saiba que o seu compilador está gerando um código sub-ótimo. Se você estiver compilando para sistemas embarcados especiais com compiladores personalizados, você poderá se deparar com este problema ainda.

    
por 21.10.2011 / 11:06
fonte
2

Eu diria que NÃO.

Pense neste cenário: seu programa travou e você precisa descobrir o que aconteceu inspecionando um dump principal ... você consegue ver a diferença? ; -)

    
por 21.10.2011 / 16:47
fonte
2

Não, você não está melhorando o código que a máquina está executando (... o código de montagem). Deixe reutilizar qualquer memória que o compilador usa para a variável para o compilador. Muitas vezes, será um registro e a reutilização não lhe comprou nada. Concentre-se em tornar o código mais fácil de ler.

    
por 21.10.2011 / 18:52
fonte
0

Depende. Em uma linguagem dinâmica, onde o tipo reside em valores em vez de variáveis, então se eu tivesse um argumento bem-nomeado para uma função que, por exemplo, fosse uma string. Eu uma mudança no algoritmo significava que ele sempre foi usado depois de ser interpretado como um inteiro, então, como um primeiro rascunho eu poderia fazer o equivalente a

scrote = int (scrote)

Mas eu acabaria procurando alterar o tipo enviado para a função e observe a alteração no tipo de parâmetro.

    
por 21.10.2011 / 13:46
fonte
0

Primeiro, olhe para o seu ambiente de desenvolvimento. Se você tiver problemas de depuração porque tem cinco variáveis em escopos diferentes com nomes idênticos, e o depurador não mostra qual dessas variáveis é a que você precisa, não use cinco variáveis com o mesmo nome. Existem duas maneiras de conseguir isso: Use uma variável ou use cinco nomes diferentes.

Seu depurador também pode dificultar a depuração de uma função com muitas variáveis. Se uma função com 20 variáveis é mais difícil de depurar do que uma com 16 variáveis, então você pode considerar a substituição de 5 variáveis por uma. ("Pode considerar" não é o mesmo que "deve sempre").

Não há problema em ter uma variável usada em vários lugares, desde que a variável sempre tenha o mesmo propósito. Por exemplo, se dez chamadas de função retornarem um código de erro, que é tratado imediatamente para cada chamada, use uma variável e não 10. Mas não use a mesma variável para coisas completamente diferentes. Como usar "nome" para um nome de cliente, e 10 linhas depois usando a mesma variável para um nome de empresa, isso é ruim e você terá problemas. Pior, usando "customerName" para um nome de cliente e 10 linhas depois usando a mesma variável "customerName" para um nome de empresa.

Importante, nada é uma regra de ferro. Tudo tem vantagens e desvantagens. Se as "melhores práticas" sugerem uma coisa e você tem razões para dizer que é uma má ideia em sua situação específica, então não faça isso.

    
por 06.07.2017 / 12:21
fonte
0

Primeiro, olhe para o seu ambiente de desenvolvimento. Se você tiver problemas de depuração porque tem cinco variáveis em escopos diferentes com nomes idênticos, e o depurador não mostra qual dessas variáveis é a que você precisa, não use cinco variáveis com o mesmo nome. Existem duas maneiras de conseguir isso: Use uma variável ou use cinco nomes diferentes.

Seu depurador também pode dificultar a depuração de uma função com muitas variáveis. Se uma função com 20 variáveis é mais difícil de depurar do que uma com 16 variáveis, então você pode considerar a substituição de 5 variáveis por uma. ("Pode considerar" não é o mesmo que "deve sempre").

Não há problema em ter uma variável usada em vários lugares, desde que a variável sempre tenha o mesmo propósito. Por exemplo, se dez chamadas de função retornarem um código de erro, que é tratado imediatamente para cada chamada, use uma variável e não 10. Há um problema com isso: geralmente, o compilador informará quando você usar uma variável não inicializada. Mas aqui, se você ler o código de erro após a chamada 6, mas a variável não foi realmente alterada após a chamada 5, você obterá dados inúteis sem o compilador avisando você. Porque a variável foi inicializada, com dados que agora são inúteis.

Importante, nada é uma regra de ferro. Tudo tem vantagens e desvantagens. Se as "melhores práticas" sugerem uma coisa e você tem razões para dizer que é uma má ideia em sua situação específica, então não faça isso.

    
por 06.07.2017 / 12:28
fonte
-2

Use variáveis globais quando precisar manter um estado ou armazenar constantes. Ao reutilizar variáveis, você está apenas reutilizando o nome que aponta para um local na memória. Nomes descritivos em inicializações só podem ganhar clareza (Assumindo Java e nenhum OCD primitivo).

A menos que você esteja em ofuscação de código manualmente ou irrita outros desenvolvedores.

    
por 22.10.2011 / 04:18
fonte