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
- Première partie
- Partie II
- Partie III
- Partie IV
- Partie V
- Partie VI
- Partie VII
- Partie VIII
- Partie IX
- Partie X
- Partie XI
- Partie XII
- Partie XIII
- Partie XIV
- XVe partie
- Partie XVI
- Partie XVII
- Partie XVIII
- Partie XIX
- Partie XX
Nous allons continuer...
Code Smell 101 - Comparaison avec les booléens
Lorsque nous comparons aux booléens, nous effectuons des moulages magiques et obtenons des résultats inattendus.
TL; DR : Ne comparez pas avec la vérité. Soit vous êtes vrai, soit faux ou vous ne devriez pas comparer
Problèmes
- Pièces moulées cachées
- La moindre violation du principe de surprise.
- Violation du principe Fail Fast
Solutions
- Utiliser des booléens
- Ne mélangez pas les booléens avec les objets booléens coulables
Le contexte
De nombreux langages convertissent les valeurs en domaines booléens croisés.
Exemple de code
Mauvais
#!/bin/bash if [ false ]; then echo "True" else echo "False" fi # this evaluates to true since # "false" is a non-empty string if [ false ] = true; then echo "True" else echo "False" fi # this also evaluates to true
Droit
#!/bin/bash if false ; then echo "True" else echo "False" fi # this evaluates to false
Détection
- [x] Automatique
Les linters peuvent rechercher des comparaisons et des avertissements explicites.
Mots clés
- Pièces moulées
Conclusion
C'est une pratique courante dans l'industrie d'utiliser de nombreux non-booléens comme booléens. Nous devrions être très stricts lorsque nous utilisons des booléens.
Rapports
Code Smell 69 - Big Bang (JavaScript Ridicule Castings)
Plus d'informations
Crédits
Photo de Michael Held sur Unsplash
Si cela ne fonctionne pas, peu importe à quelle vitesse cela ne fonctionne pas.
- Mich Ravéra
Code Odeur 102 - Code fléché
Les IF et Elses imbriqués sont très difficiles à lire et à tester
TL; DR : évitez les IF imbriqués. Encore mieux : évitez TOUS les IF
Problèmes
- Lisibilité
Solutions
- Méthode d'extraction
- Combiner des conditions booléennes
- Supprimer les IF accidentels
Le contexte
Dans le code procédural, il est très courant de voir des ifs imbriqués complexes. Cette solution est plus liée aux scripts qu'à la programmation orientée objet.
Exemple de code
Mauvais
if (actualIndex < totalItems) { if (product[actualIndex].Name.Contains("arrow")) { do { if (product[actualIndex].price == null) { // handle no price } else { if (!(product[actualIndex].priceIsCurrent())) { // add price } else { if (!hasDiscount) { // handle discount } else { // etc } } } actualIndex++; } while (actualIndex < totalCounf && totalPrice < wallet.money); } else actualIndex++; } return actualIndex; }
Droit
foreach (products as currentProduct) addPriceIfDefined(currentProduct) addPriceIfDefined() { //Several extracts }
Détection
- [x] Automatique
Étant donné que de nombreux linters peuvent analyser les arbres, nous pouvons vérifier au moment de la compilation les niveaux d'imbrication.
Mots clés
- Lisibilité
- Complexité
Conclusion
Suivant les conseils de l'oncle bob , nous devrions laisser le code plus propre que nous ne l'avons trouvé.
Refactoriser ce problème est facile.
Rapports
Code Smell 78 - L'enfer des rappels
Code Smell 03 - Les fonctions sont trop longues
Code Smell 36 - Déclarations Switch/case/elseif/else/if
Plus d'informations
Le but du génie logiciel est de contrôler la complexité, pas de la créer.
-Pamela Zave
Code Odeur 103 - Double Encapsulation
Appeler nos propres méthodes d'accès peut sembler une bonne idée d'encapsulation. Mais ce n'est pas.
TL;DR : N'utilisez pas de setters et de getters, même pour un usage privé
Problèmes
- Passeurs
- Getters
- Exposer des attributs privés
Solutions
- Supprimer les passeurs
- Supprimer les getters
- Protégez vos attributs
Le contexte
L'utilisation de la double encapsulation était une procédure standard dans les années 90.
Nous voulions cacher les détails d'implémentation même pour un usage privé.
Cela cachait une autre odeur lorsque trop de fonctions reposent sur la structure des données et une implémentation accidentelle.
Par exemple, on peut changer la représentation interne d'un objet et s'appuyer sur son protocole externe.
Le rapport coût/bénéfice n'en vaut pas la peine.
Exemple de code
Mauvais
contract MessageContract { string message = "Let's trade"; function getMessage() public constant returns(string) { return message; } function setMessage(string newMessage) public { message = newMessage; } function sendMessage() public constant { this.send(this.getMessage()); // We can access property but make a self call instead } }
Droit
contract MessageContract { string message = "Let's trade"; function sendMessage() public constant { this.send(message); } }
Détection
- [x] Semi-automatique
Nous pouvons déduire les getters et les setters et vérifier s'ils sont invoqués à partir du même objet.
Mots clés
- Encapsulation
Conclusion
La double encapsulation était une idée à la mode pour protéger une mise en œuvre accidentelle, mais elle exposait plus que protégeait.
Rapports
Code Smell 37 - Attributs protégés
Plus d'informations
Crédits
Photo de Ray Hennessy sur Unsplash
Encapsuler le concept qui varie.
-Erich Gamma
Code Odeur 104 - Affirmer Vrai
L'assertion contre les booléens rend le suivi des erreurs plus difficile.
TL; DR : N'affirmez pas vrai à moins que vous ne vérifiiez un booléen
Problèmes
- Principe d'échec rapide
Solutions
- Vérifier si la condition booléenne peut être mieux réécrite
- Favoriser assertEquals
Le contexte
Lors de l'affirmation d'un booléen, nos moteurs de test ne peuvent pas beaucoup nous aider.
Ils nous disent juste que quelque chose a échoué.
Le suivi des erreurs devient plus difficile.
Exemple de code
Mauvais
<? final class RangeUnitTest extends TestCase { function testValidOffset() { $range = new Range(1, 1); $offset = $range->offset(); $this->assertTrue(10 == $offset); // No functional essential description :( // Accidental description provided by tests is very bad } } // When failing Unit framework will show us // // 1 Test, 1 failed // Failing asserting true matches expected false :( // () <-- no business description :( // // <Click to see difference> - Two booleans // (and a diff comparator will show us two booleans)
Droit
<? final class RangeUnitTest extends TestCase { function testValidOffset() { $range = new Range(1, 1); $offset = $range->offset(); $this->assertEquals(10, $offset, 'All pages must have 10 as offset'); // Expected value should always be first argument // We add a functional essential description // to complement accidental description provided by tests } } // When failing Unit framework will show us // // 1 Test, 1 failed // Failing asserting 0 matches expected 10 // All pages must have 10 as offset <-- business description // // <Click to see difference> // (and a diff comparator will help us and it will be a great help // for complex objects like objects or jsons)
Détection
- [x] Semi-automatique
Certains linters nous avertissent si nous vérifions par rapport à booléen après avoir défini cette condition.
Nous devons le changer pour un contrôle plus spécifique.
Mots clés
- Tester les odeurs
Conclusion
Essayez de réécrire vos assertions booléennes et vous corrigerez les échecs beaucoup plus rapidement.
Rapports
Code Smell 101 - Comparaison avec les booléens
Code Odeur 07 - Variables booléennes
Plus d'informations
Crédits
Photo de Joël de Vriend sur Unsplash
J'ai enfin appris ce que signifie "compatibilité ascendante". Cela signifie que nous arrivons à garder toutes nos vieilles erreurs.
-Dennie van Tassel
Code Smell 105 - Méthodes humoristiques
Utilisez des noms professionnels et significatifs
TL; DR : Ne soyez pas informel ou offensant
Problèmes
- Lisibilité
- Travail non professionnel
Solutions
- Choisissez des noms bons et professionnels.
Le contexte
Notre métier a un côté créatif.
Parfois, nous nous ennuyons et essayons d'être drôles.
Exemple de code
Mauvais
function erradicateAndMurderAllCustomers(); // unprofessional and offensive
Droit
function deleteAllCustomers(); // more declarative and professional
Détection
- [x] Semi-automatique
Nous pouvons avoir une liste de mots interdits.
Nous pouvons également les vérifier dans les revues de code.
Les noms sont contextuels, ce serait donc une tâche difficile pour un linter automatique.
Les conventions de dénomination doivent être génériques et ne doivent pas inclure de jargon culturel.
Mots clés
- Appellation
Conclusion
Soyez professionnel dans la façon dont vous nommez les choses dans votre code.
N'essayez pas d'être un comédien en donnant à une variable un nom idiot.
Vous devez écrire du code de production afin que les futurs développeurs de logiciels (même vous) puissent facilement comprendre.
Rapports
Code Smell 38 - Noms abstraits
Plus d'informations
Crédits
Photo de Stewart Munro sur Unsplash
Cette mentalité « les utilisateurs sont des idiots et sont confus par la fonctionnalité » de Gnome est une maladie. Si vous pensez que vos utilisateurs sont des idiots, seuls les idiots l'utiliseront.
-Linus Torvalds
Excellentes citations de génie logiciel
Et c'est tout pour le moment...
Le prochain article expliquera 5 odeurs de code supplémentaires !