paint-brush
Comment trouver les parties puantes de votre code [Partie XXII]par@mcsee
787 lectures
787 lectures

Comment trouver les parties puantes de votre code [Partie XXII]

par Maximiliano Contieri8m2022/08/29
Read on Terminal Reader
Read this story w/o Javascript

Trop long; Pour lire

Ça sent mauvais parce qu'il y a probablement de nombreux cas où il pourrait être modifié ou amélioré.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Comment trouver les parties puantes de votre code [Partie XXII]
Maximiliano Contieri HackerNoon profile picture

Les odeurs de code sont un classique.

Ça sent mauvais parce qu'il y a probablement de nombreux cas où il pourrait être modifié ou amélioré.


La plupart de ces odeurs ne sont que des indices de quelque chose qui pourrait ne pas fonctionner. Ils ne sont pas obligatoirement corrigés en soi… (Vous devriez cependant y jeter un coup d'œil.)


Odeurs de code précédentes

Nous allons continuer...


Code Odeur 106 - Code dépendant de la production

N'ajoutez pas de vérification IF pour l'environnement de production.

TL ; DR : évitez d'ajouter des conditions liées à la production

Problèmes

  • Violation du principe d'échec rapide
  • Manque de testabilité

Solutions

  1. Si nécessaire, modélisez des environnements et testez-les TOUS .

Le contexte

Parfois, nous devons créer des comportements différents dans le développement et la production.

Par exemple la force des mots de passe.

Dans ce cas, nous devons configurer l'environnement avec la stratégie de force et tester la stratégie et non l'environnement lui-même.

Exemple de code

Mauvais

 def send_welcome_email(email_address, environment): if ENVIRONMENT_NAME == "production": print(f"Sending welcome email to {email_address} from Bob Builder <[email protected]>") else: print("Emails are sent only on production") send_welcome_email("[email protected]", "development") # Emails are sent only on production send_welcome_email("[email protected]", "production") # Sending welcome email to [email protected] from Bob Builder <[email protected]>

Droit

 class ProductionEnvironment: FROM_EMAIL = "Bob Builder <[email protected]>" class DevelopmentEnvironment: FROM_EMAIL = "Bob Builder Development <[email protected]>" # We can unit test environments # and even implement different sending mechanisms def send_welcome_email(email_address, environment): print(f"Sending welcome email to {email_address} from {environment.FROM_EMAIL}") # We can delegate into a fake sender (and possible logger) # and unit test it send_welcome_email("[email protected]", DevelopmentEnvironment()) # Sending welcome email to [email protected] from Bob Builder Development <[email protected]> send_welcome_email("[email protected]", ProductionEnvironment()) # Sending welcome email to [email protected] from Bob Builder <[email protected]>

Détection

  • [x] Manuel

C'est une odeur de design.

Nous devons créer des configurations de développement/production vides et les déléguer avec des objets polymorphes personnalisables.

Mots clés

  • Couplage

Conclusion

Évitez d'ajouter des conditions non testables.

Créez des configurations en déléguant les règles métier.

Utilisez des abstractions, des protocoles et des interfaces, évitez les hiérarchies strictes.

Rapports

Code Smell 56 - Préprocesseurs

Plus d'informations

Crédits

Photo par Birmingham Museums Trust sur Unsplash

Ce tweet a été inspiré par @ Jan Giacomelli

Twitter


La complexité est un signe d'immaturité technique. La simplicité d'utilisation est le vrai signe d'un produit bien conçu qu'il s'agisse d'un ATM ou d'un missile Patriot.

Daniel T.Ling

Excellentes citations de génie logiciel


Code Smell 107 - Réutilisation des variables

La réutilisation des variables rend les portées et les limites plus difficiles à suivre

TL ; DR : ne lisez pas et n'écrivez pas la même variable à des fins différentes

Problèmes

  • Lisibilité
  • Problèmes cachés

Solutions

  1. Ne réutilisez pas les variables
  2. Méthode d'extraction pour isoler les portées

Le contexte

Lors de la programmation d'un script, il est courant de réutiliser des variables.

Cela conduit à la confusion et rend le débogage plus difficile.

Nous devons réduire le champ d'application autant que possible.

Exemple de code

Mauvais

 // print line total double total = item.getPrice() * item.getQuantity(); System.out.println("Line total: " + total ); // print amount total total = order.getTotal() - order.getDiscount(); System.out.println( "Amount due: " + total ); // variable is reused

Droit

 function printLineTotal() { double total = item.getPrice() * item.getQuantity(); System.out.println("Line total: " + total ); } function printAmountTotal() { double total = order.getTotal() - order.getDiscount(); System.out.println( "Amount due: " + total ); }

Détection

  • [ ] Automatique

Les linters peuvent utiliser l'arbre d'analyse pour trouver la définition et les utilisations des variables.

Mots clés

  • Lisibilité

Conclusion

Évitez de réutiliser les noms de variables. Utilisez des noms plus spécifiques et différents.

Rapports

Code Smell 03 - Les fonctions sont trop longues

Plus d'informations

Refactoring 002 - Méthode d'extraction

Crédits

Photo de Sigmund sur Unsplash


La simplicité avant la généralité, l'usage avant la réutilisation.

Kevlin Henney

Excellentes citations de génie logiciel


Code Smell 108 - Assertions flottantes

Affirmer que deux nombres flottants sont identiques est un problème très difficile

TL; DR : Ne comparez pas les flotteurs

Problèmes

  • Résultats de test erronés
  • Essais fragiles
  • Violation du principe d'échec rapide

Solutions

  1. Évitez les flotteurs à moins que vous n'ayez de VRAIS problèmes de performances
  2. Utiliser des nombres de précision arbitraires
  3. Si vous avez besoin de comparer des flottants, comparez avec la tolérance.

Le contexte

La comparaison des nombres flottants est un vieux problème informatique.

La solution habituelle consiste à utiliser des comparaisons de seuil.

Nous vous recommandons d'éviter du tout les flottants et d'essayer d'utiliser des nombres de précision infinie.

Exemple de code

Mauvais

 Assert.assertEquals(0.0012f, 0.0012f); // Deprecated Assert.assertTrue(0.0012f == 0.0012f); // Not JUnit - Smell

Droit

 Assert.assertEquals(0.0012f, 0.0014f, 0.0002); // true Assert.assertEquals(0.0012f, 0.0014f, 0.0001); // false // last parameter is the delta threshold Assert.assertEquals(12 / 10000, 12 / 10000); // true Assert.assertEquals(12 / 10000, 14 / 10000); // false

Détection

  • [ ] Automatique

Nous pouvons ajouter une vérification avec assertEquals() sur nos frameworks de test pour éviter de vérifier les flottants.

Mots clés

  • Tester les odeurs

Conclusion

Il faut toujours éviter de comparer les flottants.

Rapports

Code Smell 71 - Des flotteurs magiques déguisés en nombres décimaux

Plus d'informations

Crédits

Photo de Mika Baumeister sur Unsplash


Dieu a fait les nombres naturels; tout le reste est l'œuvre de l'homme.

Léopold Kronecker

Excellentes citations de génie logiciel


Code Odeur 109 - Propriétés automatiques

Que se passe-t-il si vous combinez 4 odeurs de code ?

TL; DR : évitez les getters, évitez les setters, évitez la métaprogrammation. Pensez au comportement.

Problèmes

Solutions

  1. Supprimer les setters et getters automatiques

Le contexte

Les setters et les getters sont une mauvaise pratique de l'industrie.

De nombreux IDE favorisent cette odeur de code.

Certains langages fournissent un support explicite pour créer des modèles anémiques et des DTO.

Exemple de code

Mauvais

 class Person { public string name { get; set; } }

Droit

 class Person { private string name public Person(string personName) { name = personName; //imutable //no getters, no setters } //... more protocol, probably accessing private variable name }

Détection

  • [ ] Automatique

Il s'agit d'une fonctionnalité linguistique.

Nous devrions éviter les langages immatures ou interdire leurs pires pratiques.

Mots clés

  • Encapsulation

Conclusion

Nous devons bien réfléchir avant d'exposer nos propriétés.

La première étape consiste à cesser de penser aux propriétés et à se concentrer uniquement sur le comportement.

Rapports

Code Odeur 28 - Setters

Code Odeur 68 - Getters

Code Smell 70 - Générateurs de modèles anémiques

Code Odeur 40 - DTO

Code Smell 01 - Modèles anémiques

Plus d'informations

Crédits

Photo de Kony sur Unsplash


Rien n'est plus difficile que de travailler dans un délai serré et de prendre le temps de nettoyer au fur et à mesure.

Kent Beck

Excellentes citations de génie logiciel


Code Smell 110 - Commutateurs avec valeurs par défaut

Par défaut signifie "tout ce que nous ne savons pas encore". Nous ne pouvons pas prévoir l'avenir.

TL; DR : N'ajoutez pas de clause par défaut à vos dossiers. Changez-le pour une exception. Soyez explicite.

Problèmes

Solutions

  1. Remplacer si et cas par polymorphisme
  2. Changer le code par défaut en une exception

Le contexte

Lors de l'utilisation de cas, nous ajoutons généralement un cas par défaut afin qu'il n'échoue pas.

Échouer est toujours mieux que de prendre des décisions sans preuves.

Puisque le boîtier et les interrupteurs sont aussi une odeur, nous pouvons les éviter.

Exemple de code

Mauvais

 switch (value) { case value1: // if value1 matches the following will be executed.. doSomething(); break; case value2: // if value2 matches the following will be executed.. doSomethingElse(); break; default: // if value does not presently match the above values // or future values // the following will be executed doSomethingSpecial(); break; }

Droit

 switch (value) { case value1: // if value1 matches the following will be executed.. doSomething(); break; case value2: // if value2 matches the following will be executed.. doSomethingElse(); break; case value3: case value4: // We currently know these options exist doSomethingSpecial(); break; default: // if value does not match the above values we need to take a decision throw new Exception('Unexpected case ' + value + ' we need to consider it'); break; }

Détection

  • [x] Semi-automatique

Nous pouvons dire à nos linters de nous avertir des utilisations par défaut, sauf exception.

Mots clés

  • Échec rapide

Conclusion

L'écriture de code robuste ne signifie pas que nous devons prendre des décisions sans preuves.

Rapports

Code Smell 36 - Déclarations Switch/case/elseif/else/if

Plus d'informations

Crédits

Photo de Joshua Woroniecki sur Unsplash


Le coût d'ajout d'une fonctionnalité n'est pas seulement le temps qu'il faut pour la coder. Le coût comprend également l'ajout d'un obstacle à l'expansion future. L'astuce consiste à choisir les fonctionnalités qui ne se combattent pas.

Jean Carmack

Excellentes citations de génie logiciel



Et c'est tout pour le moment...

Le prochain article expliquera 5 autres odeurs de code !