Introduzindo variáveis ​​locais adicionais como substituição de comentário

12

É bom estilo usar variáveis ​​locais tecnicamente supérfluas adicionais para descrever o que está acontecendo?

Por exemplo:

bool easyUnderstandableIsTrue = (/* rather cryptic boolean expessions */);

if(easyUnderstandableIsTrue)
{
    // ...
}

Quando se trata de sobrecarga técnica, espero que o compilador otimize essa linha adicionalmente. Mas isso é considerado um inchaço de código desnecessário? Aos meus olhos, reduz o risco de comentários obsoletos.

BooleanAssange
fonte
10
"É bom estilo usar variáveis ​​locais adicionais tecnicamente supérfluas para descrever o que está acontecendo?". Sim. Não se pode dizer muito mais aqui, realmente.
David Arno
3
Acho esse estilo (ou seja, usando muitas variáveis ​​intermediárias com nomes descritivos) bastante útil ao ler meu código mais tarde. É claro que você pode escrever expressões complexas e salvar alguns nomes, não introduzindo variáveis ​​intermediárias, mas por que deseja? Ler código pode ser um grande desafio, mesmo que seja relativamente bem escrito, então não acho que complicá-lo desnecessariamente mais seja uma rota sensata.
Mael
Acredito que isso seja chamado Consolidar Expressão Condicional no catálogo de refatorações de Martin Fowler .
Brandin

Respostas:

16

Qual é o custo de ter uma variável adicional? Na maioria dos idiomas, nenhum, tanto nos idiomas compilados quanto nos interpretados.

Qual o benefício disso?

  • De maneira semelhante à extração da expressão booleana enigmática para um método separado, você está diminuindo o risco de código duplicado , mas um pouco menos do que no caso de um método separado. Se a expressão condicional for reutilizada dentro do próprio método, você poderá reutilizar a variável; se a expressão aparecer em um método diferente, você não o fará.

    Observe que, a menos que sua linguagem de programação permita que você tenha variáveis ​​locais imutáveis ​​ou que você possa impor, em termos de estilo, que nenhuma das variáveis ​​seja reatribuída, essa refatoração poderá ser arriscada a longo prazo. Se o valor da variável for alterado, pode ser muito difícil argumentar sobre o código.

  • Você está reduzindo o risco de a documentação ficar fora de sincronia com o código . Os desenvolvedores tendem a atualizar os nomes de variáveis ​​e métodos mais facilmente do que os comentários.¹ Portanto, não é incomum ver códigos como:

    // Find if the user is an actual author in order to allow her to edit the message.
    if (currentUser.isAdministrator || (message.author == currentUser && !message.locked))

A expressão provavelmente começou com if (message.author == currentUser), e depois evoluiu para lidar com o caso de mensagens bloqueadas e administradores que não precisam ser autores e não se importam com coisas bloqueadas; no entanto, o comentário não refletiu nenhuma dessas alterações.

Ambos os benefícios não são particularmente importantes, mas, dado o baixo custo de variáveis ​​adicionais, você pode realmente considerá-los.

Observe que se sua expressão booleana se tornar excessivamente complexa: ²

  • Extraia-o para um método separado e:
  • Refatore-o em várias expressões booleanas simples.

O exemplo acima se torna:

class Message
{
    ...
    public boolean canBeEditedBy(User user)
    {
        ...
        if (user.isAdministrator) {
            return true;
        }

        return this.author == user && !this.locked;
    }
}

...
if (message.canBeEditedBy(currentUser)) // See? Much more readable now!
{
    ...
}

¹ Fonte: minha própria observação de meus colegas desenvolvendo principalmente software comercial; YMMV. Uma pesquisa real pode mostrar resultados diferentes. Pessoalmente, suponho que quando os desenvolvedores leem o código, eles se concentram no código e os comentários são documentação, não código; portanto, eles geralmente não lêem comentários, por isso seria difícil esperar que eles os atualizem.

² O limite excessivamente complexo é definido com uma fórmula simples: se metade dos desenvolvedores que revisam seu código expressarem a intenção de assassiná-lo, o limite será atingido. A expressão booleana acima é simples o suficiente para exigir refatoração; no entanto, quatro partes seguidas if ((a && b) || (c && d))o tornariam potencialmente refatorável. Observe que, se a expressão for plana, o número de partes é irrelevante: if (a || b || c || d || ... || z)é legível o suficiente.

Arseni Mourzenko
fonte