Em que ponto a brevidade não é mais uma virtude?

102

Uma correção recente de bug exigia que eu revisasse o código escrito por outros membros da equipe, onde encontrei isso (é C #):

return (decimal)CostIn > 0 && CostOut > 0 ? (((decimal)CostOut - (decimal)CostIn) / (decimal)CostOut) * 100 : 0;

Agora, permitindo que haja uma boa razão para todos esses elencos, isso ainda parece muito difícil de seguir. Houve um pequeno erro no cálculo e tive que desembaraçar para corrigir o problema.

Conheço o estilo de codificação dessa pessoa a partir da revisão de código, e sua abordagem é que menor é quase sempre melhor. E, claro, há valor lá: todos nós vimos cadeias desnecessariamente complexas de lógica condicional que podem ser arrumadas com alguns operadores bem posicionados. Mas ele é claramente mais hábil do que eu em seguir cadeias de operadores amontoados em uma única declaração.

É claro que isso é uma questão de estilo. Mas alguma coisa foi escrita ou pesquisada para reconhecer o ponto em que a busca pela brevidade do código deixa de ser útil e se torna uma barreira à compreensão?

O motivo dos lançamentos é o Entity Framework. O banco de dados precisa armazená-los como tipos anuláveis. Decimal? não é equivalente a decimal em c # e precisa ser convertido.

Bob Tway
fonte
153
Quando a brevidade supera a legibilidade.
Robert Harvey
27
Olhando para o seu exemplo específico: uma conversão é (1) um lugar onde o desenvolvedor conhece mais do que o compilador e precisa informar ao compilador um fato que não pode ser deduzido, ou (2) onde alguns dados estão sendo armazenados no "erro" "tipo para os tipos de operações que precisamos executar nele. Ambos são fortes indicadores de que algo pode ser refatorado. A melhor solução aqui é encontrar uma maneira de escrever o código sem conversão.
Eric Lippert
29
Em particular, parece bizarro que seja necessário converter CostIn em decimal para compará-lo a zero, mas não CostOut; por que é que? O que há na terra é o tipo de custo em que ele só pode ser comparado a zero convertendo-o em decimal? E por que o CostOut não é do mesmo tipo que o CostIn?
Eric Lippert
12
Além disso, a lógica aqui pode realmente estar errada. Suponha que CostOutseja igual a Double.Epsilone, portanto, seja maior que zero. Mas (decimal)CostOut, nesse caso, é zero, e temos uma divisão por erro zero. O primeiro passo deve ser o de corrigir o código , o que acho que não é. Corrija, faça casos de teste e, em seguida, torne-o elegante . Código elegante e código breve têm muito em comum, mas às vezes a brevidade não é a alma da elegância.
Eric Lippert
5
A brevidade é sempre uma virtude. Mas nossa função objetiva combina concisão com outras virtudes. Se alguém pode ser mais breve sem prejudicar outras virtudes, sempre deve.
Segredo de Solomonoff

Respostas:

163

Para responder sua pergunta sobre pesquisa existente

Mas alguma coisa foi escrita ou pesquisada para reconhecer o ponto em que a busca pela brevidade do código deixa de ser útil e se torna uma barreira à compreensão?

Sim, tem havido trabalho nesta área.

Para entender essas coisas, você precisa encontrar uma maneira de calcular uma métrica para que as comparações possam ser feitas de forma quantitativa (em vez de apenas realizar a comparação com base na inteligência e na intuição, como as outras respostas). Uma métrica em potencial examinada é

Complexidade ciclomática Lines Linhas de código- fonte ( SLOC )

No seu exemplo de código, essa proporção é muito alta, porque tudo foi compactado em uma linha.

O SATC descobriu que a avaliação mais eficaz é uma combinação de tamanho e complexidade [ciclomática]. Os módulos com alta complexidade e tamanho grande tendem a ter a menor confiabilidade. Módulos com tamanho baixo e alta complexidade também são um risco de confiabilidade, pois tendem a ser um código muito conciso, difícil de alterar ou modificar.

Ligação

Aqui estão algumas referências, se você estiver interessado:

McCabe, T. e A. Watson (1994), Complexidade de Software (CrossTalk: The Journal of Defense Software Engineering).

Watson, AH e McCabe, TJ (1996). Teste Estruturado: Uma Metodologia de Teste Utilizando a Métrica da Complexidade Ciclomática (Publicação Especial NIST 500-235). Recuperado em 14 de maio de 2011, no site da McCabe Software: http://www.mccabe.com/pdf/mccabe-nist235r.pdf

Rosenberg, L., Hammer, T., Shaw, J. (1998). Métricas e confiabilidade de software (Procedimentos do Simpósio Internacional IEEE sobre Engenharia de Confiabilidade de Software). Recuperado em 14 de maio de 2011, no site da Penn State University: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.104.4041&rep=rep1&type=pdf

Minha opinião e solução

Pessoalmente, nunca avaliei a brevidade, apenas a legibilidade. Às vezes, a brevidade ajuda na legibilidade, às vezes não. O mais importante é que você esteja escrevendo o Código Realmente Óbvio (ROC) em vez do Código Somente Gravação (WOC).

Apenas por diversão, aqui está como eu escreveria e pedia aos membros da minha equipe que escrevessem:

if ((costIn <= 0) || (costOut <= 0)) return 0;
decimal changeAmount = costOut - costIn;
decimal changePercent = changeAmount / costOut * 100;
return changePercent;

Observe também que a introdução das variáveis ​​de trabalho tem o feliz efeito colateral de acionar a aritmética de ponto fixo em vez da aritmética inteira, de modo que a necessidade de todos esses lançamentos decimalé eliminada.

John Wu
fonte
4
Eu realmente gosto da cláusula de guarda para o caso menor que zero. Pode ser digno de um comentário: como um custo pode ser menor que zero, que caso especial é esse?
user949300
22
+1. Provavelmente eu adicionaria algo como:if ((costIn < 0) || (costOut < 0)) throw new Exception("costs must not be negative");
Doc Brown
13
@ DocBrown: Essa é uma boa sugestão, mas eu consideraria se o caminho do código excepcional pode ser exercido por um teste. Se sim, escreva um caso de teste que exercite esse caminho de código. Se não, altere tudo para um Assert.
Eric Lippert
12
Embora todos esses pontos sejam bons, acredito que o escopo desta questão seja: estilo de código, não lógica. Meu snip de código é um esforço de equivalência funcional de uma perspectiva de caixa preta. Lançar uma exceção não é o mesmo que retornar 0, para que a solução não seja funcionalmente equivalente.
John Wu
30
"Pessoalmente, nunca avaliei a brevidade, apenas a legibilidade. Às vezes, a brevidade ajuda na legibilidade, às vezes não." Ponto excelente . +1 apenas por isso. Também gosto da sua solução de código.
Wildcard
49

A brevidade é boa quando reduz a confusão em torno das coisas que importam, mas quando se torna concisa , compacta muitos dados relevantes com muita densidade para ser facilmente seguida, então os dados relevantes se tornam desorganizados e você tem um problema.

Nesse caso em particular, os elencos decimalestão sendo repetidos repetidamente; provavelmente seria melhor reescrevê-lo como algo como:

var decIn = (decimal)CostIn;
var decOut = (decimal)CostOut;
return decIn > 0 && CostOut > 0 ? (decOut - decIn ) / decOut * 100 : 0;
//                  ^ as in the question

De repente, a linha que contém a lógica é muito mais curta e se encaixa em uma linha horizontal, para que você possa ver tudo sem precisar rolar, e o significado é muito mais aparente.

Mason Wheeler
fonte
1
Eu provavelmente teria ido mais longe e refatorado ((decOut - decIn ) / decOut) * 100para outra variável.
FrustratedWithFormsDesigner
9
Assembler era muito mais claro: apenas uma operação por linha. Doh!
2
@FrustratedWithFormsDesigner Eu daria um passo adiante e colocaria a verificação condicional entre parênteses.
precisa saber é o seguinte
1
@FrustratedWithFormsDesigner: extrair isso para antes do condicional ignoraria a verificação de divisão por zero ( CostOut > 0), para que você tivesse que expandir o condicional para uma ifdeclaração. Não que haja algo errado com isso, mas adiciona mais verbosidade do que apenas a introdução de um local.
Whargin
1
Para ser sincero, apenas se livrar dos elencos parece que você exibiu IMO o suficiente, se alguém achar difícil ler, porque ele não consegue reconhecer um cálculo simples de taxa básica, esse é o problema dele, não o meu.
Walfrat
7

Embora eu não possa citar nenhuma pesquisa específica sobre o assunto, sugiro que todas as transmissões no seu código violem o princípio Não se repita. O que o seu código parece estar tentando fazer é converter o costIne costOutdigitar Decimal, em seguida, executar algumas checagens sobre os resultados de tais conversões, e os que executam operações adicionais sobre esses valores convertidos se os cheques passar. De fato, seu código executa uma das verificações de sanidade em um valor não convertido, aumentando a possibilidade de costOut manter um valor maior que zero, mas menor que a metade do tamanho do menor não nulo que Decimalpossa representar. O código seria muito mais claro se ele definisse variáveis ​​do tipo Decimalpara armazenar os valores convertidos e depois atuasse sobre eles.

Parece curioso que você estaria mais interessado na proporção das Decimalrepresentações de costIne do costOutque na proporção dos valores reais de costIne costOut, a menos que o código também use as representações decimais para algum outro propósito. Se o código fizer mais uso dessas representações, isso seria um argumento adicional para a criação de variáveis ​​para manter essas representações, em vez de ter uma sequência contínua de projeções em todo o código.

supercat
fonte
As conversões (decimais) provavelmente atendem a algum requisito de regra de negócios. Ao lidar com contadores, às vezes você precisa pular aros estúpidos. Eu pensei que o CFO teria um ataque cardíaco quando encontrasse a linha "Usar correção de arredondamento de impostos - US $ 0,01" que era inevitável, dada a funcionalidade solicitada. (. Fornecido: Depois de impostos preço que tenho que descobrir o preço antes de impostos As probabilidades não haverá resposta é igual à taxa de imposto..)
Loren Pechtel
@ LorenPechtel: Dado que a precisão com que o Decimalelenco será arredondado depende da magnitude do valor em questão, acho difícil imaginar regras de negócios que exijam a maneira como os elencos realmente se comportarão.
Supercat
1
Bom ponto - eu tinha esquecido os detalhes do tipo decimal, porque nunca tive a oportunidade de querer algo assim. Agora acho que isso é obediência ao culto à carga às regras de negócios - especificamente, o dinheiro não deve ser um ponto flutuante.
Loren Pechtel
1
@LorenPechtel: Para esclarecer meu último ponto: um tipo de ponto fixo pode garantir que x + yy transbordará ou produzirá y. O Decimaltipo não. O valor 1.0d / 3.0 terá mais dígitos à direita do decimal que podem ser mantidos ao usar números maiores. Portanto, adicionar e subtrair o mesmo número maior causará perda de precisão. Os tipos de ponto fixo podem perder a precisão com multiplicação ou divisão fracionária, mas não com adição, subtração, multiplicação ou divisão com o restante (por exemplo, 1,00 / 7 é 0,14 restante, 0,2; 1,00 div 0,15 é 6, restante 0,10).
Supercat
1
@ Hulk: Sim, claro. Eu estava pensando se deveria usar x + yy produzindo x, x + yx produzindo y ou x + yxy, e acabei confundindo os dois primeiros. O importante é que os tipos de ponto fixo podem garantir que muitas seqüências de operações nunca causem erros de arredondamento não detectados de qualquer magnitude. Se o código juntar as coisas de maneiras diferentes para verificar se os totais coincidem (por exemplo, comparar a soma dos subtotais da linha com a soma dos subtotais da coluna), obter resultados com precisão igual é muito melhor do que obtê-los "perto".
Supercat
5

Eu olho para esse código e pergunto "como um custo pode ser 0 (ou menos)?". Que caso especial isso indica? Código deve ser

bool BothCostsAreValidProducts = (CostIn > 0) && (CostOut > 0);
if (!BothCostsAreValidProducts)
  return NO_PROFIT;
else {
   // that calculation here...
}

Estou adivinhando os nomes aqui: altere BothCostsAreValidProductse NO_PROFITconforme apropriado.

user949300
fonte
Obviamente, os custos podem ser zero (pense no Natal apresentado). E em tempos de taxas de juros negativas custos negativos não deve ser muito surpreendente qualquer um e, pelo menos, o código deve estar preparado para lidar com isso (e seja jogando erros)
Hagen von Eitzen
Você está no caminho certo.
danny117
Isso é bobagem. if (CostIn <= 0 || CostOut <= 0)está completamente bem.
Route de milhas
Muito menos legível. O nome da variável é horrível (BothCostsAreValid seria melhor. Não há nada aqui sobre produtos). Mas mesmo isso não adiciona nada à legibilidade, porque apenas verificar CostIn, CostOut é bom. Você introduziria uma variável extra com um nome significativo se o significado da expressão que está sendo testada não for óbvio.
gnasher729 15/06
5

A brevidade deixa de ser uma virtude quando esquecemos que é um meio para um fim, e não uma virtude em si mesma. Gostamos da brevidade porque ela se correlaciona com a simplicidade, e gostamos da simplicidade porque o código mais simples é mais fácil de entender, mais fácil de modificar e conter menos bugs. No final, queremos que o código atinja esse objetivo:

  1. Cumprir os requisitos de negócios com a menor quantidade de trabalho

  2. Evite bugs

  3. Permita-nos fazer alterações no futuro que continuem cumprindo 1 e 2

Esses são os objetivos. Qualquer princípio ou método de projeto (seja KISS, YAGNI, TDD, SOLID, provas, sistemas de tipos, metaprogramação dinâmica etc.) é apenas virtuoso na medida em que nos ajuda a alcançar esses objetivos.

A linha em questão parece ter perdido o objetivo final. Embora seja curto, não é simples. Na verdade, ele contém redundância desnecessária, repetindo a mesma operação de conversão várias vezes. A repetição de código aumenta a complexidade e a probabilidade de erros. A mistura da transmissão com o cálculo real também dificulta o código.

A linha tem três preocupações: Proteções (revestimento especial 0), fundição e cálculo de tipos. Cada preocupação é bastante simples quando considerada isoladamente, mas, como tudo foi misturado na mesma expressão, torna-se difícil de seguir.

Não está claro por que CostOutnão é lançado na primeira vez em que é usado CostIn. Pode haver uma boa razão, mas a intenção não é clara (pelo menos não sem contexto), o que significa que um mantenedor deve ter cuidado em alterar esse código, pois pode haver algumas suposições ocultas. E isso é um anátema para manutenção.

Como CostIné convertido antes de comparar com 0, presumo que seja um valor de ponto flutuante. (Se fosse um int, não haveria razão para lançar). Mas se CostOutfor um ponto flutuante, o código poderá ocultar um bug obscuro de divisão por zero, pois um valor de ponto flutuante pode ser pequeno, mas diferente de zero, mas zero quando convertido para um decimal (pelo menos eu acredito que isso seria possível).

Portanto, o problema não é a brevidade ou a falta dele, o problema é a lógica repetida e a confusão de preocupações que levam a códigos difíceis de manter.

A introdução de variáveis ​​para manter os valores convertidos provavelmente aumentaria o tamanho do código contado em número de tokes, mas diminuirá a complexidade, separará as preocupações e melhorará a clareza, o que nos aproxima do objetivo do código que é mais fácil de entender e manter.

JacquesB
fonte
1
Um ponto importante: transmitir o custo uma vez em vez de duas vezes torna ilegível, porque o leitor não tem idéia se esse é um bug sutil com uma correção óbvia ou se é feito intencionalmente. Claramente, se não posso dizer com certeza o que o escritor quis dizer com uma frase, não é legível. Deve haver duas transmissões ou um comentário explicando por que o primeiro uso do CostIn não requer ou não deve ter uma transmissão.
gnasher729 15/06
3

A brevidade não é uma virtude. Legibilidade é a virtude.

A brevidade pode ser uma ferramenta para alcançar a virtude ou, como no seu exemplo, pode ser uma ferramenta para alcançar algo exatamente oposto. De uma forma ou de outra, ele carrega quase nenhum valor próprio. A regra de que o código deve ser "o mais curto possível" também pode ser substituída por "o mais obsceno possível" - todos são igualmente sem sentido e potencialmente prejudiciais se não servirem a um propósito maior.

Além disso, o código que você postou nem segue a regra da brevidade. Se as constantes fossem declaradas com o sufixo M, a maioria dos (decimal)lançamentos horríveis poderia ser evitada, pois o compilador promoveria o restante intpara decimal. Acredito que a pessoa que você está descrevendo está apenas usando a brevidade como desculpa. Provavelmente não deliberadamente, mas ainda assim.

Agent_L
fonte
2

Nos meus anos de experiência, acredito que a brevidade final é a do tempo - o tempo domina todo o resto. Isso inclui tempo de desempenho - quanto tempo um programa leva para fazer um trabalho - e tempo de manutenção - quanto tempo leva para adicionar recursos ou corrigir bugs. (Como você equilibra esses dois depende da frequência com que o código em questão está sendo executado versus aprimorado - lembre-se de que a otimização prematura ainda é a raiz de todo mal .) A brevidade do código é para melhorar a brevidade de ambos; código mais curto geralmente roda mais rápido e geralmente é mais fácil de entender e, portanto, manter. Se isso não acontecer, é um negativo líquido.

No caso mostrado aqui, acho que a brevidade do texto foi mal interpretada como brevidade da contagem de linhas, em detrimento da legibilidade, o que pode aumentar o tempo de manutenção. (Também pode levar mais tempo para executar, dependendo de como a conversão é feita, mas a menos que a linha acima seja executada milhões de vezes, provavelmente não é uma preocupação.) Nesse caso, as conversões decimais repetitivas diminuem a legibilidade, pois é mais difícil veja qual é o cálculo mais importante. Eu teria escrito da seguinte maneira:

decimal dIn = (decimal)CostIn;
decimal dOut = (decimal)CostOut;
return dIn > 0 && CostOut > 0 ? ((dOut - dIn) / dOut) * 100 : 0;

(Editar: este é o mesmo código da outra resposta, então pronto).

Sou fã do operador ternário ? :, então deixo isso lá.

Paul Brinkley
fonte
5
Os ternários são difíceis de ler, principalmente se houver alguma expressão além de um único valor ou variável nos valores retornados.
Almo
Eu me pergunto se é isso que está motivando os votos negativos. Exceto o que eu escrevi está de acordo com Mason Wheeler, atualmente com 10 votos. Ele também deixou o ternário. Não sei por que tantas pessoas têm um problema ? :- acho que o exemplo acima é suficientemente compacto, esp. comparado a um if-then-else.
Paul Brinkley
1
Realmente não tenho certeza. Eu não te votei. Não gosto de ternários, porque não está claro o que está de ambos os lados :. if-elseparece inglês: não pode perder o que isso significa.
Almo
FWIW Eu suspeito que você está recebendo votos negativos, porque esta é uma resposta muito semelhante à de Mason Wheeler, mas a dele obteve a primeira.
perfil completo de Bob Tway
1
Morte ao operador ternário !! (também, morte por abas, nem espaços e qualquer modelo de bracketing e recuo, exceto Allman (de fato, The Donald) twittou que essas serão as três primeiras leis que ele decretou no dia 20)
Marwg
2

Como quase todas as respostas acima, a legibilidade deve sempre ser seu objetivo principal. Eu também acho que a formatação pode ser uma maneira mais eficaz de conseguir isso ao criar variáveis ​​e novas linhas.

return ((decimal)CostIn > 0 && CostOut > 0) ?
       100 * ( (decimal)CostOut - (decimal)CostIn ) / (decimal)CostOut:
       0;

Concordo plenamente com o argumento da complexidade ciclomática na maioria dos casos, no entanto, sua função parece ser pequena e simples o suficiente para lidar melhor com um bom caso de teste. Por curiosidade, por que a necessidade de converter para decimal?

backpackcoder
fonte
4
O motivo dos lançamentos é o Entity Framework. O banco de dados precisa armazená-los como tipos anuláveis. Duplo? não é equivalente a Double in C # e precisa ser convertido.
Bob Tway
2
@MattThrower Você quer dizer decimal, certo? double! = decimal, há uma grande diferença.
pinkfloydx33
1
@ pinkfloydx33 yes! Digitando em um telefone com apenas metade de um cérebro envolvida :)
Bob Tway
Eu tenho que explicar aos meus alunos que os tipos de dados SQL são estranhamente diferentes dos tipos usados ​​nas linguagens de programação. Eu não fui capaz de explicar a eles o porquê . "Eu não sei!" "Pequeno endian!"
3
Eu não acho isso legível.
Almo
1

Para mim, parece que um grande problema de legibilidade aqui reside na completa falta de formatação.

Eu escreveria assim:

return (decimal)CostIn > 0 && CostOut > 0 
            ? (((decimal)CostOut - (decimal)CostIn) / (decimal)CostOut) * 100 
            : 0;

Dependendo do tipo CostIne do tipo de CostOutponto flutuante ou integral, algumas das transmissões também podem ser desnecessárias. Ao contrário de floate double, valores integrais são implicitamente promovidos para decimal.

Felix Dombek
fonte
Lamento ver que isso foi votado com pouca explicação, mas parece-me idêntico à resposta dos códigos de mochila menos algumas de suas observações, então suponho que isso seja justificado.
PJTraill
@PJTraill Devo ter perdido isso, é de fato quase idêntico. No entanto, eu prefiro ter os operadores nas novas linhas, e é por isso que vou deixar minha versão em pé.
Felix Dombek
Concordo com os operadores, como observei em um comentário sobre a outra resposta - não havia percebido que você havia feito o que eu preferia.
PJTraill
0

O código pode ser escrito às pressas, mas o código acima deve ser escrito no meu mundo com nomes de variáveis ​​muito melhores.

E se eu li o código corretamente, ele está tentando fazer um cálculo de margem bruta.

var totalSales = CostOut;
var totalCost = CostIn;
var profit = (decimal)(CostOut - CostIn);
var grossMargin = 0m; //profit expressed as percentage of totalSales

if(profit > 0)
{
    grossMargin = profit/totalSales*100
}
Thomas Koelle
fonte
3
Você perdeu a divisão por zero e retorna zero.
danny117
1
e é por isso que é complicado para refatorar código de outra pessoa que está maximizada por brevidade e por isso é bom ter comentários extras para explicar por que / como as coisas funcionam
Rudolf Olah
0

Estou assumindo que CostIn * CostOut são inteiros
É assim que eu escreveria
M (Money) é decimal

return CostIn > 0 && CostOut > 0 ? 100M * (CostOut - CostIn) / CostOut : 0M;
paparazzo
fonte
1
esperando que eles não são tanto pensamento negativo: p
Walfrat
2
O divido por zero ainda está lá?
precisa saber é o seguinte
@ danny117 Quando a brevidade produz a resposta errada, ela foi longe demais.
Paparazzo
Não deseja atualizar a pergunta e torná-la ativa. Os 100M e 0M forçam o decimal. Eu acho que (CostOut - CostIn) será executado como matemática inteira e, em seguida, a diferença é convertida em decimal.
paparazzo
0

O código é escrito para ser entendido pelas pessoas; a brevidade, neste caso, não compra muito e aumenta a carga sobre o mantenedor. Por essa brevidade, você absolutamente deve expandir isso, tornando o código mais auto-documentado (melhores nomes de variáveis) ou adicionando mais comentários explicando por que funciona dessa maneira.

Quando você escreve um código para resolver um problema hoje, esse código pode ser um problema amanhã quando os requisitos forem alterados. A manutenção sempre deve ser levada em consideração e é essencial melhorar a compreensibilidade do código.

Rudolf Olah
fonte
1
É aqui que as práticas e princípios de Engenharia de Software entram em cena. Requisitos não funcionais
hanzolo
0

A brevidade não é mais uma virtude quando

  • Há divisão sem verificação prévia de zero.
  • Não há verificação de nulo.
  • Não há limpeza.
  • Tentar pegar versus lança a cadeia alimentar onde o erro pode ser tratado.
  • São feitas suposições sobre a ordem de conclusão de tarefas assíncronas
  • Tarefas usando atraso em vez de reagendar no futuro
  • IO desnecessário é usado
  • Não está usando atualização otimista
danny117
fonte
Quando não houver uma resposta longa o suficiente.
1
Ok, isso deveria ter sido um comentário, não uma resposta. Mas ele é um cara novo, pelo menos explique; não basta votar e fugir! Bem-vindo a bordo, Danny. Cancelei a downvote, mas da próxima vez torná-lo um comentário :-)
MAWG
2
Ok, estendi a resposta para incluir algumas coisas mais complexas que aprendi da maneira mais difícil e mais fácil de escrever códigos breves.
Danny117
Obrigado pelas boas-vindas @Mawg Quero ressaltar que a verificação de nulo é o que eu encontro com os problemas mais causadores no código breve.
precisa saber é o seguinte
Acabei de editar via Android e ele não solicitou uma descrição da edição. Eu adicionei atualização otimista (detectar alterado e avisar)
danny117
0

Se isso passasse nos testes de unidade de validação, seria bom se uma nova especificação fosse adicionada, um novo teste ou uma implementação aprimorada fosse necessária e fosse necessário "desembaraçar" a dispersão do código, ou seja, quando o problema surgiria.

Obviamente, um erro no código mostra que há outro problema com a Q / A que foi uma supervisão, portanto o fato de haver um erro que não foi detectado é motivo de preocupação.

Ao lidar com requisitos não funcionais, como "legibilidade" do código, ele precisa ser definido pelo gerente de desenvolvimento e gerenciado pelo desenvolvedor líder e respeitado pelos desenvolvedores para garantir implementações adequadas.

Tente garantir uma implementação padronizada de código (padrões e convenções) para garantir a "legibilidade" e a facilidade de "manutenção". Mas se esses atributos de qualidade não forem definidos e aplicados, você terá um código como o exemplo acima.

Se você não gosta de ver esse tipo de código, tente concordar com a equipe sobre os padrões e convenções de implementação e anote-o e faça análises aleatórias de código ou verificações pontuais para confirmar se a convenção está sendo respeitada.

hanzolo
fonte