Como escrever um código legível e de fácil manutenção 30.01.17 3:57
Trabalho em equipe
Você diz "facilitar quem for mexer no código depois". Esse "quem" é muito importante. Por mais que você tenha uma forma correta de tratar do assunto tecnicamente um aspecto não pode ser deixado de lado. Politicamente você tem que levar em consideração especificamente quem é esse "quem".
Seguir o que sua equipe espera em muitos casos é mais importante que seguir regras, especialmente as regras cegas. Como você espera que um código seja fácil de manutenção se todos que provavelmente vão mexer nele não esperam e possivelmente não entendem o que você escreveu, por mais que ele esteja correto?
Fica pior se você nem sabe quem são essas pessoas, ou seja, quando você está pensando em programadores futuros que substituam você no desenvolvimento do software.
Você pode argumentar que é obrigação do programador saber usar todos os recursos da linguagem. E eu estaria com você nessa. Eu até já pedi demissão de um emprego porque me obrigavam fazer códigos tão simplistas, para o estagiário mais iniciante em programação. Não fui politicamente correto, apenas fiz uma escolha para a minha vida.
O programador comum entende melhor o estilo imperativo, ele entende como o loop funciona. Não adianta dizer que o seu código está obviamente pegando 9 elementos de uma coleção e aplicando uma fórmula a cada um desses elementos e somando todos os resultados. É óbvio para mim como isso funciona, mas não é para muita gente. Talvez o programador possa até entender, mas não sabe como mudar isso para alcançar um resultado diferente que a manutenção exige. Percebemos isto acontecendo aqui neste mesmo site o tempo todo.
E imagine em um exemplo mais complexo. O seu exemplo é simples e não é tão difícil de entender. Estou considerando que ele é apenas um exemplo curto acertadamente postado, mas o problema vai aparecer de verdade em situações mais complicadas.
Em alguns casos pode ser complicado fazer o estilo funcional corretamente já que nem sempre conhecemos a implementação. Em estilo imperativo uma ineficiência seria mais óbvia.
Eu sei que este exemplo não precisa de performance, mas o programador terá dificuldade de melhorar códigos mais complexos por não entender totalmente o que está acontecendo no código.
Eu mesmo não seguiria esta regra do mínimo denominador comum, mas esta é uma decisão minha e estou disposto a arcar com as consequências dela.
Nomes de variáveis
Fazendo uma análise específica no seu código (só nas partes que discordo do que já foi dito), afirmo que suas variáveis usam bons nomes.
Sim, variáveis devem ter nomes significativos. E as suas têm. Porque
é mais legível que
[/size]
ou porque
[/size]
é melhor que
[/size]
? (usei minúsculo simplesmente porque essa é a convenção adotada na linguagem)[/size]
Quem disse que usar
é melhor que
[/size]
. Muito longo? Eu fiz o que a "regra" manda! Mas mesmo que use só
[/size]
ele não ajuda o entendimento mais que
[/size]
em um loop.[/size]
Claro que quanto mais longe da sua declaração uma variável vai ser usada, mais o nome precisa ser significativo. Mas quando ela só vai ser usada em escopo limitado, o nome não é tão importante. Claro, não vá usar nomes aleatórios (conhecia um programador que usava palavrões em todas as variáveis). Você dosou bem.
Usar um nome com significado pode ser útil para dar semântica a uma trecho de código e evitarcomentário, mas nem sempre isso é tão importante. Comentários devem ser evitados, mas tem que analisar o contexto, é mais errado seguir uma regra cegamente.
Não é curioso que praticamente todo exemplo de código ensinando lambda usa
como argumento? Exemplos escritos por gênios da programação! Será que eles não conhecem os livros que dizem que as variáveis devem ter nomes significativos? Ou será que eles apenas sabem usar a regra da forma correta e não cegamente?[/size]
Se você for analisar bem, no seu exemplo se o argumento fosse chamado de
ou
[/size]
seria mais descritivo, mas todo mundo usa
[/size]
e ninguém que conheça o mecanismo usado deixa de entender que ali é um elemento da coleção.[/size]
A lição aqui é para tomar cuidado com regras estabelecidas. Sejam elas ditas por desconhecidos na internet ou por autores consagrados da computação.
Mesmo osmelhores mais populares livros foram escritos em contextos que a maioria das pessoas desconhecem, costumam ser vagos quando algo deve ser usado (e tem que ser mesmo, existem tantos cenários) e não costumam explicar como se chegou àquela conclusão (quando explica, não enfatiza isso, enfatiza a regra simplificada que todo mundo vai guardar). Então um livro que parece muito bom e bem intencionado acaba, por falha dos leitores, levando as pessoas cometerem barbaridades, onde a intenção era oposta. E pior, quase ninguém percebe isso. Começam usar o livro como muleta para suas atrocidades.
DRY
Para mim, um dos princípios mais importantes na codificação é o Don´t Repeat Yoursef. Ele prega que (simplificadamente) códigos não devem ser repetidos.
No seu código há repetição. Um trecho pode ser abstraído em uma função e eliminar a repetição.
Quando você tem repetição de código, fica mais difícil dar manutenção. A alteração em um ponto não garante que o outro ponto seja alterado da mesma forma.
Claro que as chances de erro no exemplo postado não são grandes. Mas elas existem.
Esse é semelhante ao problema do comentário. É comum o comentário ser repetição, até quando não parece ser. Quando você muda um código e não muda o comentário para refletir a mudança, potencialmente você pode ter uma dissonância. Lembre-se que isto não é uma regra, não estou dizendo que não deva usar comentário.
Note que abstrair em função o código repetido em questão não tornará o código mais conciso, mas fará que ele tenha a sua representação única. DRY não é para tornar código conciso. Concisão nem sempre ajuda a manutenção, ter um ponto único para alterar um algoritmo ajuda a manutenção. Desde que criar esta abstração não seja mais complicada que deixar o código inline.
Eu até admito que chego exagerar no DRY, mas ignorá-lo sempre me trouxe mais problemas de manutenção.
Também não siga o DRY cegamente.
Dicas
(não são regras)
Referências
Alguns dos livros que mais falam sobre o assunto são Clean Code e Code Complete. A versão em português não é tão boa.
Eu relutei um pouco em colocá-los porque são um pouco dogmáticos, tentam vender ideias que não funcionam tão bem assim em todas as situações, vendem ideias que parecem absolutas quando não são, e podem criar uma tendência para quem não é experiente e acha que o livro funciona como um manual. Se você não sabe como usar as dicas que os livros dão, corre o risco de se tornar dogmático também.
O primeiro enxerga uma maneira muito específica de desenvolver, praticamente obriga escolher certas ferramentas (não softwares mas paradigmas, metodologias e técnicas) para tudo. Se você souber pegar só o que é mais importante para aplicar nas suas situações poderá aproveitar bem seu conteúdo.
O segundo é um pouco mais amplo nas considerações mas tenta ser específico demais em alguns casos e não contextualiza bem. É comum dar dicas que funcionam bem em uma linguagem e não em outra mas ele não diz isto.
Observações finais
Você tem ainda um problema de legibilidade por outros fatores, principalmente por causa do ternário(eu adoro este operador) foi difícil ler o código. Parece que você ficou tão contente que conseguiu fazer tudo em uma linha, que esqueceu da legibilidade. Ou não, afinal está aqui perguntando dela :)
Manter muitas linhas de código podem afetar a manutenção também. Concisão bem pensada, e não artificial, é algo bom também. Só não pode exagerar.
Nem sempre quando uma pessoa não consegue entender seu código significa que ele seja ilegível, pode ser que você esteja lidando com um "paraquedista", cada vez mais comum no nosso meio.
Fonte: stackoverflow
Você diz "facilitar quem for mexer no código depois". Esse "quem" é muito importante. Por mais que você tenha uma forma correta de tratar do assunto tecnicamente um aspecto não pode ser deixado de lado. Politicamente você tem que levar em consideração especificamente quem é esse "quem".
Seguir o que sua equipe espera em muitos casos é mais importante que seguir regras, especialmente as regras cegas. Como você espera que um código seja fácil de manutenção se todos que provavelmente vão mexer nele não esperam e possivelmente não entendem o que você escreveu, por mais que ele esteja correto?
Fica pior se você nem sabe quem são essas pessoas, ou seja, quando você está pensando em programadores futuros que substituam você no desenvolvimento do software.
Estilo funcional X estilo imperativo
Olhando para seu código, ele tem um problema para a maioria dos programadores. Eu chutaria que 90% dos programadores que possam vir dar manutenção no seu software não entendem bem o estilo funcional de programação. Mesmo os que entendem o uso dos métodos de extensão de coleções para consultas, não entendem totalmente suas implicações (lazy evaluation e side effectspor exemplo). E o que vai acontecer quando esse programador for mexer no seu código? Ele provavelmente vai abandonar o seu e escrever a própria versão dele.Você pode argumentar que é obrigação do programador saber usar todos os recursos da linguagem. E eu estaria com você nessa. Eu até já pedi demissão de um emprego porque me obrigavam fazer códigos tão simplistas, para o estagiário mais iniciante em programação. Não fui politicamente correto, apenas fiz uma escolha para a minha vida.
O programador comum entende melhor o estilo imperativo, ele entende como o loop funciona. Não adianta dizer que o seu código está obviamente pegando 9 elementos de uma coleção e aplicando uma fórmula a cada um desses elementos e somando todos os resultados. É óbvio para mim como isso funciona, mas não é para muita gente. Talvez o programador possa até entender, mas não sabe como mudar isso para alcançar um resultado diferente que a manutenção exige. Percebemos isto acontecendo aqui neste mesmo site o tempo todo.
E imagine em um exemplo mais complexo. O seu exemplo é simples e não é tão difícil de entender. Estou considerando que ele é apenas um exemplo curto acertadamente postado, mas o problema vai aparecer de verdade em situações mais complicadas.
Em alguns casos pode ser complicado fazer o estilo funcional corretamente já que nem sempre conhecemos a implementação. Em estilo imperativo uma ineficiência seria mais óbvia.
Eu sei que este exemplo não precisa de performance, mas o programador terá dificuldade de melhorar códigos mais complexos por não entender totalmente o que está acontecendo no código.
O estagiário
Então vou lhe responder que dependendo do cenário possível de quem vai dar manutenção este código é de difícil manutenibilidade porque usa recursos que poucas pessoas estão familiarizados suficientemente.Eu mesmo não seguiria esta regra do mínimo denominador comum, mas esta é uma decisão minha e estou disposto a arcar com as consequências dela.
Nomes de variáveis
Fazendo uma análise específica no seu código (só nas partes que discordo do que já foi dito), afirmo que suas variáveis usam bons nomes.
Sim, variáveis devem ter nomes significativos. E as suas têm. Porque
- Código:
auxiliar
é mais legível que
[/size]
- Código:
aux
ou porque
[/size]
- Código:
primeiroDigitoVerificador
é melhor que
[/size]
- Código:
dv1
? (usei minúsculo simplesmente porque essa é a convenção adotada na linguagem)[/size]
Quem disse que usar
- Código:
contadorDasVezesQueAlgumaCoisaOcorreEmUmLaço
é melhor que
[/size]
- Código:
i
. Muito longo? Eu fiz o que a "regra" manda! Mas mesmo que use só
[/size]
- Código:
contador
ele não ajuda o entendimento mais que
[/size]
- Código:
i
em um loop.[/size]
Claro que quanto mais longe da sua declaração uma variável vai ser usada, mais o nome precisa ser significativo. Mas quando ela só vai ser usada em escopo limitado, o nome não é tão importante. Claro, não vá usar nomes aleatórios (conhecia um programador que usava palavrões em todas as variáveis). Você dosou bem.
Usar um nome com significado pode ser útil para dar semântica a uma trecho de código e evitarcomentário, mas nem sempre isso é tão importante. Comentários devem ser evitados, mas tem que analisar o contexto, é mais errado seguir uma regra cegamente.
Não é curioso que praticamente todo exemplo de código ensinando lambda usa
- Código:
x
como argumento? Exemplos escritos por gênios da programação! Será que eles não conhecem os livros que dizem que as variáveis devem ter nomes significativos? Ou será que eles apenas sabem usar a regra da forma correta e não cegamente?[/size]
Se você for analisar bem, no seu exemplo se o argumento fosse chamado de
- Código:
elemento
ou
[/size]
- Código:
item
seria mais descritivo, mas todo mundo usa
[/size]
- Código:
x
e ninguém que conheça o mecanismo usado deixa de entender que ali é um elemento da coleção.[/size]
A lição aqui é para tomar cuidado com regras estabelecidas. Sejam elas ditas por desconhecidos na internet ou por autores consagrados da computação.
Mesmo os
DRY
Para mim, um dos princípios mais importantes na codificação é o Don´t Repeat Yoursef. Ele prega que (simplificadamente) códigos não devem ser repetidos.
No seu código há repetição. Um trecho pode ser abstraído em uma função e eliminar a repetição.
Quando você tem repetição de código, fica mais difícil dar manutenção. A alteração em um ponto não garante que o outro ponto seja alterado da mesma forma.
Claro que as chances de erro no exemplo postado não são grandes. Mas elas existem.
Esse é semelhante ao problema do comentário. É comum o comentário ser repetição, até quando não parece ser. Quando você muda um código e não muda o comentário para refletir a mudança, potencialmente você pode ter uma dissonância. Lembre-se que isto não é uma regra, não estou dizendo que não deva usar comentário.
Note que abstrair em função o código repetido em questão não tornará o código mais conciso, mas fará que ele tenha a sua representação única. DRY não é para tornar código conciso. Concisão nem sempre ajuda a manutenção, ter um ponto único para alterar um algoritmo ajuda a manutenção. Desde que criar esta abstração não seja mais complicada que deixar o código inline.
Eu até admito que chego exagerar no DRY, mas ignorá-lo sempre me trouxe mais problemas de manutenção.
Também não siga o DRY cegamente.
Dicas
(não são regras)
- peça para outras pessoas analisarem seu código;
- experimente entender programas antigos seus;
- tente ler seu código sem ajuda de editores que "enfeitam" o código;
- conheça todas as regras de codificação e aprenda como não usá-las (como usar é fácil).
Referências
Alguns dos livros que mais falam sobre o assunto são Clean Code e Code Complete. A versão em português não é tão boa.
Eu relutei um pouco em colocá-los porque são um pouco dogmáticos, tentam vender ideias que não funcionam tão bem assim em todas as situações, vendem ideias que parecem absolutas quando não são, e podem criar uma tendência para quem não é experiente e acha que o livro funciona como um manual. Se você não sabe como usar as dicas que os livros dão, corre o risco de se tornar dogmático também.
O primeiro enxerga uma maneira muito específica de desenvolver, praticamente obriga escolher certas ferramentas (não softwares mas paradigmas, metodologias e técnicas) para tudo. Se você souber pegar só o que é mais importante para aplicar nas suas situações poderá aproveitar bem seu conteúdo.
O segundo é um pouco mais amplo nas considerações mas tenta ser específico demais em alguns casos e não contextualiza bem. É comum dar dicas que funcionam bem em uma linguagem e não em outra mas ele não diz isto.
Observações finais
Você tem ainda um problema de legibilidade por outros fatores, principalmente por causa do ternário(eu adoro este operador) foi difícil ler o código. Parece que você ficou tão contente que conseguiu fazer tudo em uma linha, que esqueceu da legibilidade. Ou não, afinal está aqui perguntando dela :)
Manter muitas linhas de código podem afetar a manutenção também. Concisão bem pensada, e não artificial, é algo bom também. Só não pode exagerar.
Nem sempre quando uma pessoa não consegue entender seu código significa que ele seja ilegível, pode ser que você esteja lidando com um "paraquedista", cada vez mais comum no nosso meio.
Fonte: stackoverflow