- Ao revisar recentemente uma base de código, houve a experiência de sentir cansaço mental apesar da qualidade do código
- Isso estava relacionado à legibilidade, mais do que à complexidade do código
- Foram identificados 8 padrões para aumentar a legibilidade do código
Métricas de legibilidade de código e métricas alternativas de complexidade
- Não existe uma métrica universal e amplamente usada para medir a legibilidade do código
- O que existe são artigos acadêmicos que não são usados na prática ou opiniões pessoais
- Em vez de criar uma nova métrica, o foco foi colocado em padrões visuais que qualquer pessoa pode discutir facilmente
- Condições importantes para uma métrica de complexidade:
- Deve funcionar em trechos de código-fonte ou funções individuais
- Deve focar na forma como o código é escrito, e não na complexidade algorítmica
- Não deve focar em elementos de estilo (nomes de variáveis, espaços em branco, indentação etc.)
Métrica de complexidade de Halstead
- Métrica de complexidade de código desenvolvida por Maurice Halstead na década de 1970
- Permite quantificar a forma como o código é escrito, independentemente da linguagem ou plataforma
- Calcula o comprimento, o volume e a dificuldade do programa com base no número de operadores e operandos
- Principais medidas:
- Número de operadores distintos (
n1)
- Número de operandos distintos (
n2)
- Número total de operadores (
N1)
- Número total de operandos (
N2)
- Quanto mais operadores e operandos forem usados, maior será a complexidade do código
- Como a definição de operadores e operandos não é clara em todas as linguagens, é importante usar ferramentas consistentes
Insights obtidos com a complexidade de Halstead
- Funções curtas e com poucas variáveis têm maior legibilidade
- O uso de operadores específicos da linguagem ou açúcar sintático (
syntactic sugar) deve ser minimizado
- O uso de cadeias na programação funcional (
map/reduce/filter etc.) perde legibilidade quando fica longo demais
Complexidade cognitiva (Cognitive Complexity)
- Métrica de complexidade desenvolvida pela SonarSource
- Uma tentativa de medir com mais precisão a dificuldade de leitura do código
- Três princípios principais:
- Construções abreviadas (
shorthand constructs) reduzem a dificuldade de leitura
- Interrupções no fluxo não linear aumentam a dificuldade
- Fluxos de controle aninhados aumentam a dificuldade
Insights obtidos com a complexidade cognitiva
- Construções abreviadas são concisas, mas trazem risco potencial de bugs
- Condicionais e operadores lógicos, quando usados em excesso, prejudicam a legibilidade
- Tratamento de exceções é uma das principais causas de aumento da complexidade do código
goto geralmente deve ser evitado, mas pode ser útil em situações específicas
- Estruturas de controle aninhadas devem ser reduzidas sempre que possível
Forma, padrões e variáveis das funções
- A “forma” visual de uma função desempenha um papel importante na legibilidade do código
- Três princípios para melhorar a legibilidade:
- Usar nomes de variáveis claros e específicos
- Evitar sombreamento de variáveis (
shadowing)
- Usar nomes visualmente distinguíveis (evitar nomes parecidos como
i e j)
- Encurtar a vida útil (
liveness) das variáveis
- Quanto menor o escopo de uso de uma variável, melhor
- Variáveis que permanecem por muito tempo além dos limites da função aumentam a complexidade
- Reutilizar padrões de código familiares
- Manter padrões de código consistentes melhora a legibilidade
- Dar preferência a padrões já conhecidos em vez de abordagens novas
8 padrões para melhorar a legibilidade do código
- Reduzir linhas/operadores/operandos – funções pequenas e poucas variáveis melhoram a legibilidade
- Evitar abordagens novas – manter padrões familiares na base de código
- Agrupamento – separar cadeias longas de funções, iteradores etc. em funções auxiliares
- Simplificar condicionais – manter condicionais curtas e minimizar a mistura de operadores lógicos
- Minimizar o
goto – quando necessário, usá-lo de forma limitada apenas no tratamento de erros
- Minimizar aninhamentos – reduzir lógica aninhada e, se necessário, separá-la em funções
- Usar nomes de variáveis claros – usar nomes específicos e sem duplicidade
- Encurtar a vida útil das variáveis – mantê-las por pouco tempo dentro da função e evitar que ultrapassem seus limites
Conclusão
- A legibilidade do código é um elemento importante da qualidade do código
- Halstead e Cognitive Complexity podem quantificar problemas de legibilidade e indicar caminhos de melhoria
- Escrever código conciso e claro facilita a manutenção e reduz a probabilidade de bugs
- Escrever um código ideal significa priorizar simplicidade, consistência e clareza
1 comentários
Opiniões do Hacker News
Encadear estruturas de programação funcional como
map,reduceefilteré conciso, mas cadeias longas tendem a prejudicar a legibilidademapefilteraleatoriamenteUm aspecto importante de um bom código é que ele é qualitativo e literário
O problema mais cansativo ao ler código é a mutabilidade
Funções pequenas e poucas variáveis geralmente são mais fáceis de ler
TypeScript torna o código difícil de ler
A função
getOddness4cria assimetriagetOddness2oferece uma escolha simétricaO artigo é interessante, mas não satisfaz
map,reduceefilter, quando bem usadas, substituem outros operadores e reduzem o “volume”A tentativa de definir legibilidade é digna de elogio
A complexidade do código é expressa pelo tamanho da árvore sintática
Em cadeias longas de funções ou callbacks, é melhor dividir em pequenos grupos e usar variáveis com nomes claros