Ç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. Par conséquent, ils ne sont pas tenus d'être corrigés en soi… (Vous devriez cependant y jeter un coup d'œil.)
Vous pouvez trouver toutes les odeurs de code précédentes (Partie I - XXVIII) ici.
Nous allons continuer...
Avez-vous déjà vu un IEngine dans la nature ?
TL; DR : Ne préfixez ni ne suffixez vos cours
Certains langages ont des conventions culturelles liées aux types de données, aux classes abstraites ou aux interfaces. Ces noms chargent nos modèles de traductions cognitives difficiles à suivre.
Nous devons nous embrasser .
public interface IEngine { void Start(); } public class ACar { } public class ImplCar { } public class CarImpl { }
public interface Engine { void Start(); } public class Vehicle { } public class Car { }
Si nous avons un thésaurus, nous pouvons pointer vers des noms maladroits.
En C#, il est courant de mettre "I" dans le nom d'une interface car, sans lui, vous ne pouvez pas dire s'il s'agit d'une interface ou d'une classe.
C'est une odeur de langue.
Utilisez de vrais noms pour vos modèles.
Photo de Tim Mossholder sur Unsplash
Certaines personnes, lorsqu'elles sont confrontées à un problème, pensent "Je sais, je vais utiliser des expressions régulières". Maintenant, ils ont deux problèmes.
Jamie Zawinski
Excellentes citations de génie logiciel
Accéder à une base de données dans des objets de domaine est une odeur de code. Le faire dans un constructeur est une double odeur.
TL; DR : Les constructeurs doivent construire (et probablement initialiser) des objets.
Sur le code hérité, la base de données n'est pas correctement séparée des objets métier.
Les constructeurs ne devraient jamais avoir d'effets secondaires.
Selon le principe de responsabilité unique, ils ne doivent construire que des objets valides
public class Person { int childrenCount; public Person(int id) { childrenCount = database.sqlCall("SELECT COUNT(CHILDREN) FROM PERSON WHERE ID = " . id); } }
public class Person { int childrenCount; // Create a class constructor for the Main class public Person(int id, int childrenCount) { childrenCount = childrenCount; // We can assign the number in the constructor // Accidental Database is decoupled // We can test the object } }
Nos linters peuvent trouver des modèles SQL sur les constructeurs et nous avertir.
La séparation des préoccupations est essentielle et le couplage est notre principal ennemi lors de la conception de logiciels robustes.
<span>Photo de Callum Hill sur Unsplash </span>
Ma conviction est toujours que si vous obtenez les structures de données et leurs invariants correctement, la plupart du code s'écrira en quelque sorte.
Pierre Deustch
Excellentes citations de génie logiciel
Certains objets sont toujours ensemble. Pourquoi ne pas les diviser ?
TL; DR : faire voyager ensemble des objets primitifs cohérents
Cette odeur est amie avec l'obsession primitive.
Si deux ou plusieurs objets primitifs sont collés ensemble, avec une logique métier répétée et des règles entre eux, nous devons trouver le concept existant de la bijection .
public class DinnerTable { public DinnerTable(Person guest, DateTime from, DateTime to) { Guest = guest; From = from; To = to; } private Person Guest; private DateTime From; private DateTime To; }
public class TimeInterval { public TimeInterval(DateTime from, DateTime to) { // We should validate From < To From = from; To = to; } } public DinnerTable(Person guest, DateTime from, DateTime to) { Guest = guest; Interval = new TimeInterval(from, to); } // Even Better... public DinnerTable(Person guest, Interval reservationTime) { Guest = guest; Interval = reservationTime; }
La détection basée sur les motifs de cohésion est disponible sur quelques linters.
Regroupez le comportement au bon endroit et masquez les données primitives.
Code Smell 122 - Obsession primitive
Code Smell 01 - Modèles anémiques
Code Smell 27 - Tableaux associatifs
Photo de Dynamic Wang sur Unsplash
Le cœur du logiciel est sa capacité à résoudre les problèmes liés au domaine pour son utilisateur. Toutes les autres fonctionnalités, aussi vitales soient-elles, soutiennent cet objectif fondamental.
Eric Evans
Excellentes citations de génie logiciel
Nous avons beaucoup entendu parler des NFT. Maintenant, nous maîtrisons le concept Fungible.
TL;DR : Respectez le MAPPER . Rendre fongible ce qui est fongible dans le monde réel et vice-versa.
Selon Wikipédia :
La fongibilité est la propriété d'un bien ou d'une marchandise dont les unités individuelles sont essentiellement interchangeables et dont chacune des parties est indiscernable d'une autre partie.
Dans les logiciels, on peut remplacer des objets fongibles par d'autres.
Lors de la cartographie de nos objets avec des objets réels, nous oublions parfois le modèle partiel et construisons sur la conception.
public class Person implements Serializable { private final String firstName; private final String lastName; public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } } shoppingQueueSystem.queue(new Person('John', 'Doe'));
public class Person { } shoppingQueueSystem.queue(new Person()); // The identity is irrelevant for queue simulation
C'est une odeur sémantique.
Nous devons comprendre le modèle pour vérifier s'il est correct ou non.
Rendre fongible ce qui est fongible et vice-versa.
Cela semble facile mais nécessite des compétences en conception et évite la complexité accidentelle.
Photo par Andrey Metelev sur Unsplash
Les gens pensent que l'informatique est l'art des génies mais la réalité est le contraire, juste beaucoup de gens font des choses qui se construisent les unes sur les autres, comme un mur de mini pierres.
Donald Knuth
N'utilisez pas l'évaluation booléenne comme raccourci de lisibilité.
TL; DR : N'utilisez pas la comparaison booléenne pour les fonctions d'effets secondaires.
Les programmeurs intelligents aiment écrire du code hacky et obscur même lorsqu'il n'y a aucune preuve solide de cette amélioration.
Une optimisation prématurée nuit toujours à la lisibilité.
userIsValid() && logUserIn(); // this expression is short circuit // Does not value second statement // Unless the first one is true functionDefinedOrNot && functionDefinedOrNot(); // in some languages undefined works as a false // If functionDefinedOrNot is not defined does // not raise an error and neither runs
if (userIsValid()) { logUserIn(); } if(typeof functionDefinedOrNot == 'function') { functionDefinedOrNot(); } // Checking for a type is another code smell
Nous pouvons vérifier si les fonctions sont impures et changer le court-circuit en IF.
Certains linters réels nous avertissent de ce problème
N'essayez pas d'avoir l'air intelligent.
Nous ne sommes plus dans les années 50.
Soyez un développeur d'équipe.
Code Smell 140 - Évaluation des courts-circuits
Code Smell 06 - Programmeur trop malin
Code Smell 149 - Enchaînement optionnel
Photo de Michael Dziedzic sur Unsplash
Un ordinateur est une machine stupide capable de faire des choses incroyablement intelligentes, tandis que les programmeurs informatiques sont des gens intelligents capables de faire des choses incroyablement stupides. Ils sont, en bref, un match parfait.
Bill Bryson
Article suivant : 5 autres odeurs de code.