Ç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.)
Nous allons continuer...
N'ajoutez pas de vérification IF pour l'environnement de production.
TL ; DR : évitez d'ajouter des conditions liées à la production
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.
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]>
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]>
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.
É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.
Code Smell 56 - Préprocesseurs
Photo par Birmingham Museums Trust sur Unsplash
Ce tweet a été inspiré par @ Jan Giacomelli
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
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
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.
// 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
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 ); }
Les linters peuvent utiliser l'arbre d'analyse pour trouver la définition et les utilisations des variables.
Évitez de réutiliser les noms de variables. Utilisez des noms plus spécifiques et différents.
Code Smell 03 - Les fonctions sont trop longues
Refactoring 002 - Méthode d'extraction
La simplicité avant la généralité, l'usage avant la réutilisation.
Kevlin Henney
Excellentes citations de génie logiciel
Affirmer que deux nombres flottants sont identiques est un problème très difficile
TL; DR : Ne comparez pas les flotteurs
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.
Assert.assertEquals(0.0012f, 0.0012f); // Deprecated Assert.assertTrue(0.0012f == 0.0012f); // Not JUnit - Smell
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
Nous pouvons ajouter une vérification avec assertEquals() sur nos frameworks de test pour éviter de vérifier les flottants.
Il faut toujours éviter de comparer les flottants.
Code Smell 71 - Des flotteurs magiques déguisés en nombres décimaux
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
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.
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.
class Person { public string name { get; set; } }
class Person { private string name public Person(string personName) { name = personName; //imutable //no getters, no setters } //... more protocol, probably accessing private variable name }
Il s'agit d'une fonctionnalité linguistique.
Nous devrions éviter les langages immatures ou interdire leurs pires pratiques.
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.
Code Smell 70 - Générateurs de modèles anémiques
Code Smell 01 - Modèles anémiques
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
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.
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.
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; }
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; }
Nous pouvons dire à nos linters de nous avertir des utilisations par défaut, sauf exception.
L'écriture de code robuste ne signifie pas que nous devons prendre des décisions sans preuves.
Code Smell 36 - Déclarations Switch/case/elseif/else/if
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 !