Minimiser les effets secondaires (idéalement n'en avoir aucun)
Il est beaucoup plus difficile de raisonner et de maintenir une fonction qui provoque 3 changements d’états en dehors de sa propre portée qu’une fonction qui introduit simplement quelque chose et en sort autre chose. Vous ne pouvez pas simplement savoir ce que la fonction fait, vous devez vous rappeler ce qu’elle a fait et comment cela affecte toutes les autres fonctions pertinentes.
Réduire le poids des effets secondaires signifie aussi des classes avec moins de membres, et en particulier moins de membres pouvant modifier l’état de la classe, car les fonctions membres peuvent modifier des états au-delà des leurs et avoir des effets secondaires (elles peuvent manipuler les éléments internes de la classe, par exemple). Cela signifie également que les classes ont moins de données membres propres, de sorte qu'il y a moins d'état de manipulation de ces méthodes et moins d'effets secondaires qu'elles peuvent causer.
Comme exemple simple, imaginons d’essayer de concevoir une structure de données sophistiquée pouvant conserver un sorted
état qu’elle utilise pour déterminer s’il faut effectuer des recherches binaires ou linéaires. Dans un tel cas, il pourrait être utile de séparer le dessin en deux classes. L'appel sorted
de la classe non triée peut alors renvoyer une structure de données d'une autre classe qui conserve toujours son contenu trié. Maintenant, vous avez moins d’effets secondaires (donc moins de code source d’erreurs et plus facile à comprendre) ainsi que des codes plus largement applicables (l’ancienne conception gaspillerait à la fois en termes de traitement et d’efficacité intellectuelle pour les petites baies qui n’auraient pas besoin d’être triées).
Évitez les dépendances externes superflues
Vous pourrez peut-être implémenter le code le plus complexe imaginable avec une réutilisation maximale du code en utilisant 13 bibliothèques différentes pour accomplir une tâche relativement simple. Cependant, cela entraîne une surcharge intellectuelle chez vos lecteurs en leur faisant comprendre au moins certaines parties de 13 bibliothèques différentes. Quiconque a essayé de construire et de comprendre une bibliothèque tierce nécessitant l’installation et la construction d’une douzaine d’autres bibliothèques pour pouvoir fonctionner doit immédiatement comprendre cette complexité inhérente.
C'est probablement une vue très controversée, mais je préférerais une duplication de code modeste à l'extrême opposé, à condition que le résultat final soit bien testé (rien de pire que du code défectueux non testé dupliqué à plusieurs reprises). Si vous avez le choix entre 3 lignes de code dupliqué pour calculer un produit vectoriel vectoriel ou en intégrant une bibliothèque mathématique épique uniquement pour réduire 3 lignes de code, je suggérerais le premier, à moins que toute votre équipe ne soit impliquée dans cette bibliothèque mathématique. , à ce stade, vous pouvez toujours envisager d'écrire simplement 3 lignes de code au lieu de 1 si cela est assez trivial en échange des avantages du découplage.
La réutilisation de code est un acte d'équilibre. Si vous en utilisez trop et que vous transférez la complexité intellectuelle de manière un-à-plusieurs, les 3 lignes de code simples que vous avez enregistrées ci-dessus entraînent des coûts qui obligent les lecteurs et les responsables de la maintenance à comprendre plus d'informations que 3 lignes de code. . Cela rend également votre code moins stable, car si la bibliothèque mathématique change, votre code le peut aussi. Si vous en utilisez trop peu et que vous multipliez les coûts intellectuels, votre code cesse de bénéficier d’améliorations centralisées; pour un résultat aussi difficile à maintenir, sinon plus, que l'extrême opposé.
Testez la merde
C’est un acquis, mais si votre code ne gère pas tous les cas de saisie et manque certains cas, comment pouvez-vous espérer que les autres conservent le code que vous avez écrit et que vous n’avez même pas corrigé avant de le transférer aux yeux et aux mains? Il est déjà assez difficile d’apporter des modifications au code qui fonctionne parfaitement, sans parler du code qui n’a jamais été tout à fait correct.
De plus, le code qui passe des tests approfondis trouvera généralement moins de raisons de changer. Cela concerne la stabilité, qui est encore plus difficile à atteindre que la maintenabilité, car un code stable qui ne doit jamais être modifié n’entraîne aucun coût de maintenance.
Documentation d'interface
Si vous ne pouvez pas consacrer autant de temps à documenter les deux, donnez la priorité à "ce que font les choses" et non "à la façon dont les choses fonctionnent". Une interface claire et claire dans ses intentions quant à ce qu’elle fera (ou à tout le moins, ce qu’elle est censée faire) dans tous les cas possibles de saisie donnera un contexte plus clair à sa propre mise en œuvre, ce qui guidera non seulement la d'utiliser le code, mais aussi comment cela fonctionne.
En attendant, le code qui manque de ces qualités là où les gens ne savent même pas ce qu'il est censé faire est SOL, peu importe la précision de ses détails d'implémentation. Un manuel de 20 pages sur la manière dont le code source est implémenté est sans valeur pour les personnes qui ne savent même pas exactement comment il est censé être utilisé et ce qu'il est même supposé faire dans tous les scénarios possibles.
Pour ce qui est de la mise en œuvre, donnez la priorité à la documentation de ce que vous faites différemment des autres. Par exemple, Intel a une hiérarchie de volumes englobante pour ses noyaux de lancer de rayons. Depuis que je travaille dans ce domaine, je peux reconnaître l'essentiel de ce que fait leur code en un coup d'œil sans passer au crible la documentation. Cependant, ils font quelque chose d'unique qui est l'idée de traverser le BVH et d'effectuer des intersections en parallèle en utilisant des paquets de rayons . C'est là que je veux qu'ils hiérarchisent leur documentation, car ces parties du code sont exotiques et inhabituelles de la plupart des implémentations historiques de BVH.
Lisibilité
Cette partie est très subjective. Je ne me soucie pas vraiment de la lisibilité d’un type proche du processus de la pensée humaine. Le code le mieux documenté décrivant les choses au plus haut niveau reste difficile pour moi si l'auteur utilise des processus de pensée bizarres et compliqués pour résoudre un problème. En attendant, un code concis utilisant 2 ou 3 noms de caractères peut souvent être plus facile à comprendre si la logique est très simple. Je suppose que vous pouvez examiner par des pairs et voir ce que les autres préfèrent.
Je m'intéresse surtout à la maintenabilité et, plus important encore, à la stabilité. Le code qui ne trouve aucune raison de changer est un code qui ne nécessite aucun coût de maintenance.