FRFAM.COM >> Famille >> Technologie &Innovation >> Informatique

Votre code peut sentir ! Comment le réparer

Une odeur de code est un morceau de code ou un modèle de codage général qui semble indiquer un problème plus profond dans la structure globale et la conception d'une base de code.

Considérez une odeur de code comme tout signe suggérant qu'une section de code doit être refactorisée. Ce n'est pas que le code est bogué ou non fonctionnel – souvent, le code malodorant fonctionne très bien – mais le code malodorant est souvent difficile à maintenir et à étendre, ce qui peut entraîner des problèmes techniques (en particulier sur les grands projets).

Dans cet article, nous mettrons en évidence 10 des odeurs de code les plus courantes, ce qu'il faut rechercher et comment les désodoriser. Si vous êtes un nouveau programmeur, évitez-les et votre code sera sensiblement meilleur !

1. Couplage serré

Le problème

Un couplage étroit se produit lorsque deux objets dépendent tellement des données et/ou des fonctions l'un de l'autre que la modification de l'un nécessite la modification de l'autre. Lorsque deux objets sont trop étroitement couplés, apporter des modifications au code peut être un cauchemar et vous êtes plus susceptible d'introduire des bogues à chaque modification.

Par exemple :

classe Ouvrier { 
Vélo vélo =nouveau Vélo();
public void commute() {
bike.drive();
}
}

Dans ce cas, Worker et Bike sont étroitement couplés. Et si un jour vous vouliez conduire une voiture au lieu d'un vélo pour vos déplacements ? Vous devez entrer dans la classe Worker et remplacer tout le code lié au vélo par le code lié à la voiture. C'est désordonné et sujet aux erreurs.

La solution

Vous pouvez desserrer le couplage en ajoutant une couche d'abstraction. Dans ce cas, la classe Worker ne veut pas seulement conduire des vélos, mais aussi des voitures, et peut-être des camions, peut-être même des scooters. Ce sont tous des véhicules, n'est-ce pas ? Créez donc une interface de véhicule, qui vous permet d'insérer et de remplacer différents types de véhicules à votre guise :

classe Ouvrier { 
Véhicule automobile ;
public void changeVehicle(Vehicle v) {
véhicule =v ;
}
public void commute() {
véhicule.drive();
}
}
Interface Véhicule {
annuler le lecteur ();
}
classe Vélo met en œuvre Véhicule {
lecteur vide public() {
}
}
classe Voiture met en œuvre Véhicule {
lecteur vide public() {
}
}

2. Objets divins

Le problème

Un objet Dieu est une classe/module massif qui contient trop de variables et de fonctions. Il "en sait trop" et "en fait trop", ce qui est problématique pour deux raisons. Premièrement, d'autres classes/modules deviennent trop dépendants de celui-ci pour les données (couplage étroit). Deuxièmement, la structure globale du programme devient confuse car tout est entassé au même endroit.

La solution

Prenez un objet Dieu, séparez ses données et ses fonctions en fonction des problèmes qu'elles doivent résoudre, puis transformez ces groupements en objets. Si vous avez un objet Dieu, il peut être préférable qu'il soit une composition de plusieurs objets plus petits.

Par exemple, supposons que vous ayez une classe User monstrueuse :

utilisateur de classe { 
nom d'utilisateur de chaîne publique ;
mot de passe de chaîne publique ;
adresse de chaîne publique ;
public String code postal ;
l'âge public;
...
chaîne publique getUsername() {
retourner le nom d'utilisateur ;
}
public void setUsername(String u) {
nom d'utilisateur =u ;
}
}

Vous pouvez le convertir en une composition des éléments suivants :

utilisateur de classe { 
informations d'identification;
Profil profil ;
...
}
Identifiants de classe {
nom d'utilisateur de chaîne publique ;
mot de passe de chaîne publique ;
...
chaîne publique getUsername() {
retourner le nom d'utilisateur ;
}
public void setUsername(String u) {
nom d'utilisateur =u ;
}
}

La prochaine fois que vous aurez besoin de modifier les procédures de connexion, vous n'aurez pas à parcourir une énorme classe d'utilisateurs car la classe Credentials est plus facile à gérer !

3. Fonctions longues

Le problème

Une fonction longue est exactement ce à quoi elle ressemble :une fonction qui est devenue trop longue. Bien qu'il n'y ait pas de nombre spécifique pour le nombre de lignes de code "trop ​​longues" pour une fonction, c'est l'une de ces choses où vous le savez quand vous le voyez. C'est à peu près une version plus restreinte du problème de l'objet Dieu :une fonction longue a trop de responsabilités.

La solution

Les fonctions longues doivent être divisées en plusieurs sous-fonctions, chaque sous-fonction étant conçue pour gérer une tâche ou un problème unique. Idéalement, la fonction longue d'origine se transformera en une liste d'appels de sous-fonctions, rendant le code plus propre et plus facile à lire.

4. Paramètres excessifs

Le problème

Une fonction (ou un constructeur de classe) qui nécessite trop de paramètres est problématique pour deux raisons. Premièrement, cela rend le code moins lisible et le rend plus difficile à tester. Mais deuxièmement, et plus important encore, cela peut indiquer que l'objectif de la fonction est trop ambigu et tente de gérer trop de responsabilités.

La solution

Bien que "trop" soit subjectif pour une liste de paramètres, nous vous recommandons de vous méfier de toute fonction qui a plus de 3 paramètres. Bien sûr, il est parfois logique d'avoir une seule fonction avec 5 ou même 6 paramètres, mais seulement s'il y a une très bonne raison à cela.

La plupart du temps, il n'y en a pas et le code ferait mieux de diviser cette fonction en deux ou plusieurs fonctions différentes. Contrairement à l'odeur de code "Fonctions longues", celle-ci ne peut pas être résolue simplement en remplaçant le code par des sous-fonctions :la fonction elle-même doit être divisée et divisée en fonctions distinctes couvrant des responsabilités distinctes.

5. Identifiants mal nommés

Le problème

Noms de variable à une ou deux lettres. Noms de fonction indescriptibles. Noms de classe trop ornés. Marquage des noms de variables avec leur type (par exemple, b_isCounted pour une variable booléenne). Et le pire de tout, mélanger différents schémas de nommage dans une seule base de code. Tout cela se traduit par un code difficile à lire, difficile à comprendre et difficile à maintenir.

La solution

Choisir de bons noms pour les variables, les fonctions et les classes est une compétence difficile à apprendre. Si vous rejoignez un projet existant, parcourez-le et voyez comment les identifiants existants sont nommés. S'il existe un guide de style, mémorisez-le et respectez-le. Pour les nouveaux projets, envisagez de créer votre propre guide de style et respectez-le.

En général, les noms de variables doivent être courts mais descriptifs. Les noms de fonction doivent généralement avoir au moins un verbe et il doit être immédiatement évident ce que la fonction fait juste à partir de son nom, mais évitez de bourrer trop de mots. Il en va de même pour les noms de classe.

6. Numéros magiques

Le problème

Vous parcourez un code que (espérons-le) quelqu'un d'autre a écrit et vous repérez des nombres codés en dur. Peut-être qu'ils font partie d'une instruction if, ou peut-être font-ils partie de calculs mystérieux qui ne semblent pas avoir de sens. Vous devez modifier la fonction, mais vous n'arrivez pas à comprendre ce que signifient les chiffres. Cue head scratching.

La solution

Lors de l'écriture de code, ces soi-disant "nombres magiques" doivent être évités à tout prix. Les nombres codés en dur ont un sens au moment où ils sont écrits, mais ils peuvent rapidement perdre tout sens, en particulier lorsque quelqu'un d'autre essaie de maintenir votre code.

Une solution consiste à laisser des commentaires expliquant le nombre, mais la meilleure option consiste à convertir les nombres magiques en variables constantes (pour les calculs) ou en énumérations (pour les instructions conditionnelles et les instructions de commutation). En donnant un nom aux nombres magiques, le code devient infiniment plus lisible en un coup d'œil et moins sujet aux modifications erronées.

7. Imbrication profonde

Le problème

Il existe deux façons principales de se retrouver avec du code profondément imbriqué :les boucles et les instructions conditionnelles. Le code profondément imbriqué n'est pas toujours mauvais, mais peut être problématique car il peut être difficile à analyser (surtout si les variables ne sont pas bien nommées) et encore plus difficile à modifier.

La solution

Si vous vous retrouvez à écrire une boucle for double, triple ou même quadruple, votre code essaie peut-être d'aller trop loin de lui-même pour trouver des données. Au lieu de cela, fournissez un moyen pour que les données soient demandées via un appel de fonction sur n'importe quel objet ou module contenant les données.

D'un autre côté, les instructions conditionnelles profondément imbriquées sont souvent le signe que vous essayez de gérer trop de logique dans une seule fonction ou classe. En fait, imbrication profonde et fonctions longues ont tendance à aller de pair. Si votre code comporte des instructions switch massives ou des instructions if-then-else imbriquées, vous pouvez implémenter un modèle de machine d'état ou de stratégie à la place.

L'imbrication profonde est particulièrement répandue chez les programmeurs de jeux inexpérimentés !

8. Exceptions non gérées

Le problème

Les exceptions sont puissantes mais facilement abusées. Les programmeurs paresseux qui utilisent incorrectement les instructions throw-catch peuvent rendre le débogage exponentiellement plus difficile, voire impossible. Par exemple, ignorer ou enterrer les exceptions interceptées.

La solution

Au lieu d'ignorer ou d'enterrer les exceptions interceptées, imprimez au moins la trace de la pile de l'exception afin que les débogueurs aient quelque chose avec quoi travailler. Laisser votre programme échouer en silence est une recette pour de futurs maux de tête, c'est garanti ! Préférez également intercepter des exceptions spécifiques plutôt que des exceptions générales. Apprenez-en plus dans notre article sur la façon de gérer les exceptions de la bonne manière.

9. Dupliquer le code

Le problème

Vous exécutez la même logique exacte dans plusieurs domaines non liés de votre programme. Plus tard, vous vous rendez compte que vous devez modifier cette logique, mais vous ne vous souvenez pas de tous les endroits où vous l'avez implémentée. Vous finissez par le changer à seulement 5 endroits sur 8, ce qui entraîne des comportements buggés et incohérents.

La solution

Le code dupliqué est un candidat de choix pour être transformé en fonction. Par exemple, supposons que vous développiez une application de chat et que vous écriviez ceci :

Chaîne queryUsername =getSomeUsername(); 
boolean isUserOnline =false ;
pour (chaîne nom d'utilisateur :onlineUsers) {
if (username.equals(queryUsername)) {
isUserOnline =vrai ;
}
}
si (estUtilisateurEn Ligne) {
...
}

Ailleurs dans le code, vous vous rendez compte que vous devez effectuer la même chose "est-ce que cet utilisateur est en ligne?" Chèque. Au lieu de copier-coller la boucle, vous pouvez l'extraire dans une fonction :

public boolean isUserOnline(String queryUsername) { 
pour (chaîne nom d'utilisateur :onlineUsers) {
if (username.equals(queryUsername)) {
retourner vrai ;
}
}
retourner faux ;
}

Désormais, n'importe où dans votre code, vous pouvez utiliser la vérification isUserOnline(). Si jamais vous avez besoin de modifier cette logique, vous pouvez modifier la méthode et elle s'appliquera partout où elle est appelée.

10. Manque de commentaires

Le problème

Le code n'a absolument aucun commentaire nulle part. Pas de blocs de documentation pour les fonctions, pas d'aperçu de l'utilisation des classes, pas d'explications des algorithmes, etc. On pourrait dire qu'un code bien écrit n'a pas besoin de commentaires, mais la vérité est que même le code le mieux écrit demande encore plus d'énergie mentale pour comprendre que l'anglais.

La solution

L'objectif d'une base de code facile à maintenir doit être un code suffisamment bien écrit pour qu'il n'en ait pas besoin commentaires, mais les a toujours. Et lorsque vous rédigez des commentaires, visez des commentaires qui expliquent pourquoi un extrait de code existe au lieu d'expliquer quoi ça fait. Les commentaires sont bons pour l'âme et la santé mentale. Ne les négligez pas.

Comment écrire du code qui ne sent pas

Aussi évident que cela puisse paraître, la plupart des odeurs de code proviennent d'un malentendu ou d'une négligence des bons principes et modèles de programmation. Par exemple, une adhésion solide au principe DRY élimine la plupart des doublons de code, tandis que la maîtrise du principe de responsabilité unique rend presque impossible la création d'objets divins monstrueux.

Nous vous recommandons également de lire notre article sur la façon d'écrire du code plus propre, qui examine un côté plus pratique de la programmation. Si vous ne pouvez pas lire votre propre code et le comprendre en un coup d'œil, comment quelqu'un d'autre le fera-t-il ? Un code propre est un code inodore.

Qu'est-ce qui vous pose le plus de problèmes en matière de programmation ? Partagez avec nous dans les commentaires ci-dessous !

Crédit image :SIphotography/Depositphotos


[]