À quel moment la brièveté n'est-elle plus une vertu?


102

Une correction de bogue récente m'a obligé à passer en revue le code écrit par d'autres membres de l'équipe, où j'ai trouvé ceci (c'est C #):

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

Maintenant, admettant qu'il y ait une bonne raison pour tous ces lancers, cela semble toujours très difficile à suivre. Il y avait un bug mineur dans le calcul et j'ai dû le démêler pour résoudre le problème.

Je connais le style de codage de cette personne lors de la révision du code, et son approche est que raccourcir est presque toujours préférable. Et bien sûr, il y a une valeur à cela: nous avons tous vu des chaînes inutilement complexes de logique conditionnelle qui pourraient être mises de l'ordre avec quelques opérateurs bien placés. Mais il est clairement plus apte que moi à suivre des chaînes d'opérateurs regroupés dans une seule déclaration.

Bien entendu, c’est finalement une question de style. Mais est-ce que quelque chose a été écrit ou fait des recherches pour reconnaître le point où aspirer à la brièveté du code cesse d'être utile et devient un obstacle à la compréhension?

La raison des conversions est Entity Framework. La base de données doit les stocker en tant que types nullables. Décimal? n’est pas équivalent à Decimal en C # et doit être converti.


153
Quand la brièveté l'emporte sur la lisibilité.
Robert Harvey

27
En regardant votre exemple spécifique: une distribution est soit (1) un endroit où le développeur en sait plus que le compilateur et doit dire au compilateur un fait qui ne peut pas être déduit, ou (2) où certaines données sont stockées dans le "mauvais "type pour les types d'opérations que nous devons effectuer dessus. Les deux sont des indicateurs forts que quelque chose pourrait être refactorisé. La meilleure solution ici consiste à trouver un moyen d'écrire le code sans transtypage.
Eric Lippert

29
En particulier, il semble étrange qu’il soit nécessaire de convertir CostIn en décimal pour le comparer à zéro, mais pas CostOut; pourquoi donc? Quel est le type de CostIn sur Terre qui ne peut être comparé à zéro qu'en le convertissant en décimal? Et pourquoi CostOut n'est-il pas du même type que CostIn?
Eric Lippert

12
De plus, la logique peut en réalité être fausse. Suppose CostOutest égal à Double.Epsilon, et est donc supérieur à zéro. Mais (decimal)CostOutest dans ce cas zéro, et nous avons une erreur de division par zéro. La première étape devrait consister à obtenir le code correct , ce qui, à mon avis, ne l’est pas. Corrigez-le, créez des cas de test, puis rendez-le élégant . Le code élégant et le code bref ont beaucoup en commun, mais parfois la brièveté n'est pas l'âme de l'élégance.
Eric Lippert

5
La brièveté est toujours une vertu. Mais notre fonction objective combine la brièveté avec d’autres vertus. Si on peut être plus bref sans nuire aux autres vertus, on devrait toujours le faire.
Le secret de Solomonoff

Réponses:


163

Pour répondre à votre question sur la recherche existante

Mais est-ce que quelque chose a été écrit ou fait des recherches pour reconnaître le point où aspirer à la brièveté du code cesse d'être utile et devient un obstacle à la compréhension?

Oui, il y a eu des travaux dans ce domaine.

Pour bien comprendre ces éléments, vous devez trouver un moyen de calculer une métrique afin de pouvoir effectuer des comparaisons quantitatives (plutôt que de procéder à une comparaison basée sur l’esprit et l’intuition, comme le font les autres réponses). Une mesure potentielle qui a été examinée est

Complexité cyclomatique ÷ Lignes de code source ( SLOC )

Dans votre exemple de code, ce rapport est très élevé, car tout a été compressé sur une seule ligne.

La SATC a constaté que l'évaluation la plus efficace est une combinaison de taille et de complexité [Cyclomatic]. Les modules avec une complexité élevée et une taille importante tendent à présenter la fiabilité la plus basse. Les modules de taille réduite et de complexité élevée présentent également un risque de fiabilité, car ils ont tendance à être un code très laconique, difficile à modifier ou à modifier.

Lien

Voici quelques références si vous êtes intéressé:

McCabe, T. et A. Watson (1994), Complexité logicielle (CrossTalk: le journal du génie logiciel de la défense).

Watson, AH et McCabe, TJ (1996). Tests structurés: méthodologie de test utilisant la métrique de complexité cyclomatique (publication spéciale NIST 500-235). Extrait le 14 mai 2011 du site Web de McCabe Software: http://www.mccabe.com/pdf/mccabe-nist235r.pdf.

Rosenberg, L., T. Hammer, J. Shaw (1998). Métriques et fiabilité des logiciels (Actes du symposium international IEEE sur l’ingénierie de la fiabilité des logiciels). Extrait le 14 mai 2011 du site Web de la Penn State University: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.104.4041&rep=rep1&type=pdf.

Mon avis et solution

Personnellement, je n'ai jamais apprécié la brièveté, seulement la lisibilité. Parfois, la brièveté améliore la lisibilité, parfois non. Ce qui est plus important, c’est que vous écrivez un code vraiment lisible (ROC) au lieu d’un code en écriture seule (WOC).

Juste pour le plaisir, voici comment je l'écrirais et demanderais aux membres de mon équipe de l'écrire:

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

Notez également que l’introduction des variables de travail a l’effet secondaire heureux de déclencher une arithmétique en virgule fixe au lieu d’une arithmétique entière, decimaléliminant ainsi la nécessité de tous ces conversions .


4
J'aime beaucoup la clause de garde pour le cas inférieur à zéro. Peut-être un commentaire digne de ce nom: comment un coût peut-il être inférieur à zéro, quel cas particulier est-ce?
user949300

22
+1 J'ajouterais probablement quelque chose du genreif ((costIn < 0) || (costOut < 0)) throw new Exception("costs must not be negative");
Doc Brown le

13
@ DocBrown: C'est une bonne suggestion, mais je voudrais déterminer si le chemin de code exceptionnel peut être exercé par un test. Si oui, alors écrivez un scénario de test qui utilise ce chemin de code. Si non, alors changez le tout en assert.
Eric Lippert

12
Bien que tous ces points soient positifs, je pense que la portée de cette question concerne le style du code et non la logique. Mon code snip est un effort d'équivalence fonctionnelle du point de vue d'une boîte noire. Lancer une exception n'est pas la même chose que renvoyer 0, donc cette solution ne serait pas fonctionnellement équivalente.
John Wu

30
"Personnellement, je n'ai jamais attaché de valeur à la brièveté, seulement à la lisibilité. Parfois, la brièveté améliore la lisibilité, parfois non." Excellent point. +1 juste pour ça. J'aime votre solution de code, aussi.
Wildcard

49

La brièveté est bonne quand elle réduit l'encombrement autour des objets qui importent, mais quand elle devient concise , contenant trop de données pertinentes trop étroitement pour être facilement suivies, les données pertinentes deviennent elles-mêmes encombrées et vous avez un problème.

Dans ce cas particulier, les moulages decimalsont répétés encore et encore; dans l’ensemble, il serait probablement préférable de le réécrire comme suit:

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

Soudain, la ligne contenant la logique est beaucoup plus courte et s'adapte à une ligne horizontale, de sorte que vous pouvez tout voir sans avoir à faire défiler l'écran, et la signification est beaucoup plus évidente.


1
J'aurais probablement été plus loin et refactored ((decOut - decIn ) / decOut) * 100à une autre variable.
FrustratedWithFormsDesigner

9
L'assembleur était beaucoup plus clair: une seule opération par ligne. Doh!

2
@FrustratedWithFormsDesigner J'irais même plus loin et encapsuler la vérification conditionnelle entre parenthèses.
Chris Cirefice

1
@FrustratedWithFormsDesigner: Si vous extrayez cela avant que la condition ne contourne la vérification par division (par zéro CostOut > 0), vous devez développer cette condition en une ifinstruction. Cela n’a rien de mal à cela, mais cela ajoute plus de verbosité que la simple introduction d’un local.
wchargin

1
Pour être honnête, le simple fait de se débarrasser des moulages semble être comme si vous aviez diffusé assez d'IMO, si quelqu'un avait du mal à lire parce qu'il ne pouvait pas reconnaître un calcul simple du taux de base, c'est son problème, pas le mien.
Walfrat

7

Bien que je ne puisse citer aucune recherche particulière sur le sujet, je suggérerais que tous les moulages de votre code enfreignent le principe «Ne vous répétez pas». Ce que votre code semble essayer de faire est de convertir le type costInet le costOuten type Decimal, puis d'effectuer des contrôles de cohérence sur les résultats de ces conversions et d'exécuter des opérations supplémentaires sur ces valeurs converties si les contrôles aboutissent. En fait, votre code effectue l'un des contrôles de cohérence sur une valeur non convertie, ce qui augmente la possibilité que costOut contienne une valeur supérieure à zéro, mais inférieure à la moitié de la taille de la plus petite valeur non nulle Decimalpouvant être représentée. Le code serait beaucoup plus clair s'il définissait des variables de type Decimalpour contenir les valeurs converties, puis agissait sur celles-ci.

Il semble curieux que le rapport entre les Decimalreprésentations de costInet et costOutles valeurs réelles de costInet costOut, vous intéresse davantage , à moins que le code n'utilise également les représentations décimales à d'autres fins. Si le code doit utiliser davantage ces représentations, ce serait un argument supplémentaire pour la création de variables destinées à contenir ces représentations, plutôt que d'avoir une séquence continue de transtypages dans le code.


Les conversions (décimales) doivent probablement répondre à certaines exigences de la règle de gestion. Lorsque vous traitez avec des comptables, vous devez parfois sauter à travers des cerceaux stupides. Je pensais que le CFO allait avoir une crise cardiaque quand il a trouvé la ligne "Utiliser la correction de l'arrondi de l'impôt - 0,01 $" qui était inévitable compte tenu de la fonctionnalité demandée. (Fourni: prix après impôt. Je dois calculer le prix avant impôt. Les chances qu'il n'y ait pas de réponse correspondent au taux d'imposition.)
Loren Pechtel le

@ LorenPechtel: Etant donné que la précision d'une Decimaldistribution dépend de l'ampleur de la valeur en question, il m'est difficile d'imaginer des règles commerciales qui imposeraient un comportement réel des acteurs .
Supercat

1
Bon point - j'avais oublié les détails du type décimal parce que je n'ai jamais eu l'occasion de vouloir quelque chose comme ça. Je pense maintenant que c’est une obéissance des règles commerciales au culte des cargos - c’est-à-dire que l’argent ne doit pas être un élément flottant.
Loren Pechtel

1
@ LorenPechtel: Pour clarifier mon dernier point: un type à point fixe peut garantir que x + yy débordera ou donnera y. Le Decimaltype ne le fait pas. La valeur 1.0d / 3.0 aura plus de chiffres à la droite de la décimale que ce qui peut être maintenu en utilisant des nombres plus grands. Donc, ajouter et soustraire le même nombre plus grand entraînera une perte de précision. Les types à point fixe peuvent perdre en précision avec la multiplication ou la division fractionnelle, mais pas avec l'addition, la soustraction, la multiplication ou la division avec le reste (par exemple, 1,00 / 7 correspond à 0,14 reste 0,2; 1,00 div 0,15 correspond à 6 reste 0,10).
Supercat

1
@ Hulk: Oui, bien sûr. Je me demandais s'il fallait utiliser x + yy pour donner x, x + yx pour donner y ou x + yxy, et j'ai fini par mélanger les deux premiers. Ce qui est important, c'est que les types à virgule fixe puissent garantir que de nombreuses séquences d'opérations ne provoqueront jamais d'erreurs d'arrondis non détectées, quelle que soit leur ampleur. Si le code additionne les éléments de différentes manières pour vérifier la concordance des totaux (par exemple, en comparant la somme des sous-totaux de lignes à la somme des sous-totaux de colonnes), il est bien préférable d'avoir des résultats exactement égaux, plutôt que de les rendre "proches".
Supercat

5

Je regarde ce code et demande "comment un coût peut-il être égal à 0 (ou moins)?". Quel cas particulier cela indique-t-il? Le code devrait être

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

Je devine quant aux noms ici: changer BothCostsAreValidProductset NO_PROFITcomme approprié.


Bien sûr, les coûts peuvent être nuls (pensez aux cadeaux de Noël). Et en période de taux d'intérêt négatifs, les coûts négatifs ne devraient pas non plus être trop surprenants et au moins le code devrait être prêt à y faire face (et même en jetant des erreurs)
Hagen von Eitzen -

Vous étes sur le bon chemin.
danny117

Cela est bête. if (CostIn <= 0 || CostOut <= 0)est tout à fait bien.
Miles Rout

Beaucoup moins lisible. Le nom de la variable est horrible (BothCostsAreValid serait meilleur. Il n’ya rien ici sur les produits). Mais même cela n’ajoute rien à la lisibilité, car rien que vérifier CostIn, CostOut. Vous introduirez une variable supplémentaire avec un nom explicite si la signification de l'expression testée n'est pas évidente.
gnasher729

5

La brièveté cesse d’être une vertu quand on oublie que c’est un moyen de parvenir à une fin plutôt qu’une vertu en soi. Nous aimons la brièveté parce que cela correspond à la simplicité, et nous aimons la simplicité, car un code simple est plus facile à comprendre et à modifier et contient moins de bogues. En fin de compte, nous voulons que le code atteigne ces objectifs:

  1. Répondre aux exigences de l'entreprise avec le moins de travail possible

  2. Éviter les insectes

  3. Permettez-nous d’apporter à l’avenir des changements qui continuent à remplir les objectifs 1 et 2

Ce sont les objectifs. Tous les principes ou méthodes de conception (qu’il s’agisse de KISS, YAGNI, TDD, SOLID, preuves, systèmes de types, métaprogrammation dynamique, etc.) ne sont vertueux que dans la mesure où ils nous aident à atteindre ces objectifs.

La ligne en question semble avoir manqué de vue l'objectif final. Bien que ce soit court, ce n'est pas simple. En fait, il contient une redondance inutile en répétant plusieurs fois la même opération de transtypage. La répétition de code augmente la complexité et la probabilité de bogues. Mélanger le casting avec le calcul réel rend également le code difficile à suivre.

La ligne a trois préoccupations: gardes (boîtier spécial 0), type casting et calcul. Chaque problème est assez simple lorsqu'il est pris isolément, mais parce qu'il a été mélangé dans la même expression, il devient difficile à suivre.

Il n’est pas clair pourquoi CostOutla première fois, elle n’est pas utilisée CostIn. Il peut y avoir une bonne raison, mais l'intention n'est pas claire (du moins sans contexte), ce qui signifie qu'un responsable serait prudent de ne pas modifier ce code car il pourrait y avoir des hypothèses cachées. Et ceci est un anathème pour la maintenabilité.

Puisque CostInest jeté avant de comparer à 0, je suppose que c'est une valeur à virgule flottante. (Si c'était un int, il n'y aurait aucune raison de lancer). Mais si CostOutest un float, le code pourrait masquer un bogue obscur de division par zéro, puisqu’une valeur en virgule flottante peut être petite mais non nulle, mais nulle lorsqu’elle est convertie en décimale (du moins, j’estime que cela serait possible.)

Le problème n'est donc pas la brièveté ni l'absence de concision, le problème est une logique répétée et une confusion des préoccupations menant à un code difficile à maintenir.

L'introduction de variables pour conserver les valeurs exprimées augmenterait probablement la taille du code compté en nombre de touches, mais réduirait la complexité, dissocierait les préoccupations et améliorerait la clarté, ce qui nous rapprocherait de l'objectif d'un code plus facile à comprendre et à gérer.


1
Un point important: Casting CostIn une fois au lieu de deux le rend illisible, car le lecteur n'a aucune idée s'il s'agit d'un bogue subtil avec un correctif évident, ou si cela est fait intentionnellement. Clairement, si je ne peux pas dire avec certitude ce que l'auteur a voulu dire par une phrase, alors ce n'est pas lisible. Il doit y avoir soit deux conversions, soit un commentaire expliquant pourquoi la première utilisation de CostIn ne nécessite pas ou ne devrait pas avoir de casting.
gnasher729

3

La brièveté n'est pas une vertu du tout. La lisibilité est la vertu.

La brièveté peut être un outil pour atteindre la vertu, ou, comme dans votre exemple, peut être un outil permettant de réaliser quelque chose de totalement opposé. De cette façon ou d'une autre, il n'a presque aucune valeur en soi. La règle selon laquelle le code doit être "aussi court que possible" peut également être remplacée par "aussi obscène que possible" - elles sont toutes également dénuées de sens et peuvent être dommageables si elles ne servent pas un objectif plus ambitieux.

De plus, le code que vous avez posté ne suit même pas la règle de brièveté. Si les constantes avaient été déclarées avec le suffixe M, la plupart des (decimal)moulages horribles pourraient être évités, car le compilateur encouragerait rester intà decimal. Je crois que la personne que vous décrivez utilise simplement la brièveté comme excuse. Probablement pas délibérément, mais quand même.


2

Au cours de mes années d'expérience, j'en suis venu à croire que la brièveté ultime est celle du temps - le temps domine tout le reste. Cela inclut à la fois le temps d'exécution - le temps nécessaire à un programme pour effectuer un travail - et le temps nécessaire à la maintenance - le temps nécessaire pour ajouter des fonctionnalités ou corriger des bogues. (La manière dont vous équilibrez les deux dépend de la fréquence à laquelle le code en question est exécuté par rapport à l'amélioration. Rappelez-vous que l' optimisation prématurée est toujours la racine de tout mal .) La brièveté du code a pour but d'améliorer la brièveté des deux; Un code plus court est généralement plus rapide, plus facile à comprendre et donc à maintenir. Si ce n'est pas le cas, alors c'est un net négatif.

Dans le cas présenté ici, je pense que la brièveté du texte a été mal interprétée comme une brièveté du nombre de lignes, au détriment de la lisibilité, ce qui peut augmenter le temps de maintenance. (Cela peut également prendre plus de temps, en fonction de la façon dont le lancer est effectué, mais à moins que la ligne ci-dessus ne soit exécutée des millions de fois, ce n'est probablement pas un problème.) Dans ce cas, les conversions décimales répétitives nuisent à la lisibilité, car il est plus difficile de voyez quel est le calcul le plus important. J'aurais écrit comme suit:

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

(Edit: c'est le même code que l'autre réponse, alors voilà.)

Je suis un fan de l'opérateur ternaire ? :, donc je laisserais ça dans.


5
Les ternaires sont difficiles à lire, en particulier s'il existe des expressions au-delà d'une valeur unique ou d'une variable dans les valeurs renvoyées.
Almo

Je me demande si c'est ce qui motive les votes négatifs. Sauf que ce que j'ai écrit est en accord avec Mason Wheeler, actuellement à 10 voix. Il a également quitté le ternaire. Je ne sais pas pourquoi tant de gens ont un problème avec ? :- je pense que l'exemple ci-dessus est suffisamment compact, esp. comparé à un si-alors-sinon.
Paul Brinkley

1
Vraiment pas sûr. Je ne vous ai pas voté. Je n'aime pas les ternaires parce qu'on ne sait pas ce qui se trouve de chaque côté de la :. if-elselit comme anglais: ne peut pas rater ce que cela signifie.
Almo

FWIW Je suppose que vous obtenez des votes défavorables car il s’agit d’une réponse très similaire à celle de Mason Wheeler, mais la sienne a eu son premier.
Bob Tway

1
Mort à l'opérateur ternaire !! (aussi, la mort aux onglets, ni les espaces et tout modèle de bracketing & indentation sauf Allman (en fait, The Donald (tm) a tweeté que ce seront les trois premières lois qu'il édicte le 20)
Mawg

2

Comme presque toutes les réponses ci-dessus, la lisibilité devrait toujours être votre objectif principal. Cependant, je pense aussi que le formatage peut être un moyen plus efficace d’atteindre cet objectif en créant des variables et de nouvelles lignes.

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

Je suis tout à fait d'accord avec l'argument de la complexité cyclomatique dans la plupart des cas, mais votre fonction semble être assez petite et assez simple pour être mieux traitée avec un bon cas de test. Par curiosité, pourquoi la nécessité de convertir en décimal?


4
La raison des conversions est Entity Framework. La base de données doit les stocker en tant que types nullables. Double? n’est pas équivalent à Double en C # et doit être jeté.
Bob Tway

2
@MattThrower Vous voulez dire decimal, non? double! = decimal, il y a une grande différence.
pinkfloydx33

1
@ pinkfloydx33 oui! Taper sur un téléphone avec seulement un demi-cerveau engagé :)
Bob Tway

Je dois expliquer à mes étudiants que les types de données SQL sont étrangement différents de ceux utilisés dans les langages de programmation. Je n'ai pas été en mesure de leur expliquer pourquoi . "Je ne sais pas!" "Petit endian!"

3
Je ne trouve pas cela lisible du tout.
Almo

1

Pour moi, il semble qu'un gros problème de lisibilité réside dans l'absence totale de formatage.

Je l'écrirais comme ceci:

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

Selon qu'il s'agisse d'un type CostInet d' CostOutun type à virgule flottante ou d'un type intégral, certains transtypages peuvent également être inutiles. Contrairement à floatet double, les valeurs intégrales sont implicitement promues decimal.


Je suis désolé de voir que cela a été voté sans explication, mais cela me semble identique à la réponse de backpackcodes moins certaines de ses remarques, donc je suppose que cela était justifié.
PJTraill

@PJTraill J'ai dû rater ça, c'est presque identique. Cependant, je préfère fortement avoir les opérateurs sur les nouvelles lignes, c'est pourquoi je vais laisser ma version en attente.
Felix Dombek

Je suis d'accord sur les opérateurs, comme je l'ai fait remarquer dans un commentaire sur l'autre réponse - je n'avais pas remarqué que vous l'aviez fait comme je le préfère.
PJTraill

0

Le code peut être écrit rapidement, mais le code ci-dessus devrait dans mon monde être écrit avec des noms de variables bien meilleurs.

Et si je lis correctement le code, il essaie de faire un calcul de grossmargin.

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
}

3
Vous avez perdu la division par zéro renvoie zéro.
danny117

1
et c'est pourquoi il est difficile de remanier le code de quelqu'un d'autre qui est optimisé pour plus de concision et pourquoi il est bon d'avoir des commentaires supplémentaires pour expliquer pourquoi / comment les choses fonctionnent
Rudolf Olah

0

Je suppose que CostIn * CostOut sont des entiers
Voici comment je l' écrirais
M (Money) est décimal

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

1
en espérant qu'ils ne soient pas tous les deux une pensée négative: p
Walfrat le

2
La division par zéro est-elle toujours là?
danny117

@ danny117 Lorsque la brièveté donne une réponse fausse, elle est allée trop loin.
paparazzo

Je ne veux pas mettre à jour la question et la rendre active. Le 100M et le 0M forcent la décimale. Je pense que (CostOut - CostIn) sera exécuté sous forme de calcul mathématique entier, puis la différence est convertie en décimal.
paparazzo

0

Le code est écrit pour être compris par les gens; la brièveté dans ce cas n’achète pas beaucoup et alourdit la charge du mainteneur. Pour cette brièveté, vous devez absolument le développer en rendant le code plus auto-documenté (de meilleurs noms de variables) ou en ajoutant plus de commentaires expliquant pourquoi il fonctionne de cette manière.

Lorsque vous écrivez du code pour résoudre un problème aujourd'hui, ce code risque de poser problème demain lorsque les exigences changent. La maintenance doit toujours être prise en compte et l'amélioration de la compréhensibilité du code est essentielle.


1
C’est là que les pratiques et les principes du génie logiciel entrent en jeu. Exigences non fonctionnelles
hanzolo

0

La brièveté n'est plus une vertu quand

  • Il existe une division sans contrôle préalable pour zéro.
  • Il n'y a pas de vérification pour null.
  • Il n'y a pas de nettoyage.
  • TRY CATCH par rapport à la chaîne alimentaire où l'erreur peut être gérée.
  • Des hypothèses sont formulées sur l'ordre d'exécution des tâches asynchrones
  • Tâches utilisant le délai au lieu de reprogrammer à l'avenir
  • Inutile IO est utilisé
  • Ne pas utiliser la mise à jour optimiste

Quand il n'y a pas assez longtemps Réponse.

1
Ok, cela aurait dû être un commentaire, pas une réponse. Mais il est un nouveau gars, alors au moins expliquer; ne vous contentez pas de voter et de vous enfuir! Bienvenue à bord, Danny. J'ai annulé un vote négatif, mais la prochaine fois, faites un commentaire :-)
Mawg

2
Ok, j'ai élargi la réponse pour inclure des choses plus complexes que j'ai apprises à la dure et la manière facile d'écrire un code bref.
danny117

Merci pour l'accueil @Mawg Je tiens à souligner le contrôle de null est ce que je rencontre les problèmes les plus générateurs de code bref.
danny117

Je viens de modifier via Android et il n'a pas demandé une description de la modification. J'ai ajouté une mise à jour optimiste (détecter changé et avertir)
danny117

0

Si cela réussissait les tests unitaires de validation, alors tout irait bien, si une nouvelle spécification était ajoutée, si un nouveau test ou une mise en œuvre améliorée était requise, et il était nécessaire de "démêler" la légèreté du code, c'est-à-dire lorsque problème se poserait.

De toute évidence, un bogue dans le code indique qu’il ya un autre problème avec Q / A, qui est un oubli. Par conséquent, le fait qu’un bogue n’ait pas été détecté est une source de préoccupation.

Lorsqu'il s'agit d'exigences non fonctionnelles telles que la "lisibilité" du code, il doit être défini par le responsable du développement, géré par le développeur principal et respecté par les développeurs afin de garantir une implémentation correcte.

Essayez d’assurer une mise en œuvre normalisée du code (normes et conventions) afin d’assurer la "lisibilité" et la facilité de "maintenabilité". Mais si ces attributs de qualité ne sont pas définis et appliqués, vous obtiendrez un code comme dans l'exemple ci-dessus.

Si vous n'aimez pas voir ce type de code, essayez de faire en sorte que l'équipe soit d'accord sur les normes et les conventions de mise en œuvre, écrivez-le et faites des examens de code aléatoires ou des contrôles inopinés pour valider que la convention est respectée.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.