Une odeur de code (code smell) désigne un fragment de code ou un pattern indiquant un problème sous-jacent dans la structure et la conception d'une base de code.
Considérez une odeur de code comme un signal d'alarme : le code fonctionne souvent, mais il est difficile à maintenir et à étendre, surtout sur de grands projets. Cela augmente les risques de bugs lors des modifications.
Dans cet article, découvrez les 10 odeurs de code les plus fréquentes, leurs signes distinctifs et des solutions concrètes pour les refactoriser. Pour les débutants, les éviter dès le départ améliorera radicalement votre code !
Le problème
Le couplage serré survient quand deux classes dépendent étroitement des données ou méthodes de l'une et l'autre. Toute modification d'une classe impacte l'autre, rendant les mises à jour risquées et propices aux erreurs.
Exemple :
class Ouvrier {
Velo velo = new Velo();
public void commute() {
velo.drive();
}
}Ici, Ouvrier est lié à Velo. Changer pour une Voiture nécessite de modifier Ouvrier, ce qui est source d'erreurs.
La solution
Introduisez une abstraction via une interface. Ouvrier utilise un Véhicule générique :
class Ouvrier {
Vehicule vehicule;
public void changeVehicule(Vehicule v) {
vehicule = v;
}
public void commute() {
vehicule.drive();
}
}
interface Vehicule {
void drive();
}
class Velo implements Vehicule {
public void drive() { /* ... */ }
}
class Voiture implements Vehicule {
public void drive() { /* ... */ }
}Le problème
Un objet divin est une classe surchargée en variables et méthodes. Elle " sait " et " fait " trop, favorisant le couplage serré et une architecture confuse.
La solution
Découpez en objets spécialisés. Transformez l'objet divin en composition d'objets plus petits.
Exemple : Une classe User monstrueuse devient :
class Utilisateur {
Identifiants identifiants;
Profil profil;
// ...
}
class Identifiants {
public String nomUtilisateur;
public String motDePasse;
// Getters/setters
}Les modifications ciblées (ex. : login) sont plus simples.
Le problème
Une fonction trop longue assume trop de responsabilités, rendant le code illisible et difficile à tester.
La solution
Divisez-la en sous-fonctions monotâches. La fonction principale orchestre les appels, améliorant lisibilité et maintenabilité.
Le problème
Plus de 3-4 paramètres rend le code illisible, difficile à tester et signale souvent une responsabilité diffuse.
La solution
Séparez en fonctions distinctes. Évitez les >3 paramètres sauf raison impérieuse ; préférez objets ou builders.
Le problème
Noms courts/abscurs (a, b), verbaux ou mélangeant conventions (camelCase/snake_case) nuisent à la compréhension.
La solution
Adoptez un guide de style : variables descriptives et courtes, fonctions avec verbe (getUserInfo()), classes nommées précisément. Respectez les conventions du projet.
Le problème
Chiffres codés en dur (ex. : if (x > 42)) perdent leur sens hors contexte.
La solution
Remplacez par constantes nommées (MAX_AGE = 42) ou enums. Ajoutez commentaires "pourquoi" si nécessaire.
Le problème
Boucles ou if imbriqués (4+ niveaux) compliquent lecture et maintenance.
La solution
Extrayez en fonctions. Pour if/switch massifs, utilisez machines d'état ou patterns Stratégie.
Le problème
Ignorer ou masquer exceptions empêche le débogage.
La solution
Loggez la stack trace. Catch exceptions spécifiques. Lisez notre guide sur la gestion d'exceptions.
Le problème
Logique répétée mène à des incohérences lors des mises à jour.
La solution
Extrayez en fonction réutilisable :
public boolean isUserOnline(String queryUsername) {
for (String username : onlineUsers) {
if (username.equals(queryUsername)) {
return true;
}
}
return false;
}Le problème
Absence de docs rend le code opaque, même bien écrit.
La solution
Commentez le "pourquoi", pas le "quoi". Documentez APIs, algos complexes.
Respectez DRY (Don't Repeat Yourself) et SRP (Single Responsibility Principle). Lisez notre article sur le code propre. Un code lisible au premier regard est maintenable.
Quelle odeur vous gêne le plus ? Dites-le en commentaires !
Crédit image : SIphotography/Depositphotos
[]