jeudi 4 avril 2024

Clean Code

 Le Clean Code est une philosophie de développement qui vise à écrire du code lisible, compréhensible, maintenable et efficace. Il ne s'agit pas seulement de faire fonctionner le code, mais de le rendre facile à comprendre et à modifier par d'autres développeurs (ou par soi-même plus tard !).

Ce concept a été popularisé par Robert C. Martin (Uncle Bob) dans son livre Clean Code: A Handbook of Agile Software Craftsmanship.


Les Principes du Clean Code

1. Nommer clairement les variables, fonctions et classes

✅ Un bon nom doit être descriptif et explicite.
❌ Éviter les abréviations et les noms vagues.

// ❌ Mauvais : Trop court et pas explicite
int a; 
double calc(double x, double y) { return x * y; }

// ✅ Bon : Décrit précisément le rôle de la variable ou fonction
int nombreUtilisateursActifs;
double CalculerPrixTotal(double prixUnitaire, double quantite) { return prixUnitaire * quantite; }

2. Écrire des fonctions courtes et avec un seul objectif (Single Responsibility)

✅ Une fonction doit faire une seule chose et bien la faire.
❌ Éviter les fonctions trop longues et complexes.

// ❌ Mauvais : Une seule fonction fait plusieurs choses (connexion + récupération de données + affichage)
void GérerUtilisateur()
{
    ConnexionUtilisateur();
    var data = RécupérerDonnées();
    Console.WriteLine(data);
}

// ✅ Bon : Séparation des responsabilités
void ConnexionUtilisateur() { /* ... */ }
List<string> RécupérerDonnées() { /* ... */ return new List<string>(); }
void AfficherDonnées(List<string> data) { Console.WriteLine(data); }

3. Éviter les commentaires inutiles

✅ Le code doit être auto-documenté, c’est-à-dire compréhensible sans commentaires excessifs.
❌ Éviter les commentaires évidents.

// ❌ Mauvais commentaire : inutile, car le code est clair
int age = 25; // Assigner l'âge à 25

// ✅ Bon commentaire : Justifié, car le code peut prêter à confusion
// Attention : Si l'âge est inférieur à 18, l'accès est refusé.
if (age < 18) { RefuserAccès(); }

4. Éviter la duplication de code (DRY - Don't Repeat Yourself)

✅ Si un même bloc de code est utilisé plusieurs fois, il faut le factoriser dans une fonction.
❌ Éviter de copier-coller la même logique dans plusieurs endroits.

// ❌ Mauvais : Duplication du code pour l'affichage du message
void AfficherMessageErreur()
{
    Console.WriteLine("Une erreur s'est produite");
}

void AfficherMessageSuccès()
{
    Console.WriteLine("Une erreur s'est produite"); // Dupliqué !
}

// ✅ Bon : Factorisation dans une fonction commune
void AfficherMessage(string message)
{
    Console.WriteLine(message);
}

5. Éviter les dépendances inutiles

✅ Respecter le principe SOLID pour une architecture propre et modulaire.
❌ Ne pas mélanger plusieurs responsabilités dans une même classe.

// ❌ Mauvais : Une classe qui fait trop de choses (connexion + gestion des utilisateurs)
class GestionUtilisateur
{
    public void Connexion() { /* ... */ }
    public void RécupérerUtilisateur() { /* ... */ }
    public void EnregistrerUtilisateur() { /* ... */ }
}

// ✅ Bon : Séparation des responsabilités
class ServiceAuthentification
{
    public void Connexion() { /* ... */ }
}

class ServiceUtilisateur
{
    public void RécupérerUtilisateur() { /* ... */ }
    public void EnregistrerUtilisateur() { /* ... */ }
}

6. Gérer correctement les exceptions

✅ Gérer les erreurs proprement pour éviter les crashs imprévus.
❌ Ne pas laisser d'exceptions non gérées.

// ❌ Mauvais : Catch vide qui cache l'erreur
try
{
    var data = File.ReadAllText("data.txt");
}
catch (Exception) { } // Mauvaise pratique !

// ✅ Bon : Log de l'erreur
try
{
    var data = File.ReadAllText("data.txt");
}
catch (Exception ex)
{
    Console.WriteLine($"Erreur lors de la lecture du fichier : {ex.Message}");
}

7. Respecter la cohérence et la simplicité

✅ Le code doit être cohérent et prévisible dans sa structure.
❌ Ne pas utiliser des structures complexes si une solution simple existe.

// ❌ Mauvais : Trop complexe pour juste vérifier une condition
bool EstAdulte(int age)
{
    if (age >= 18)
        return true;
    else
        return false;
}

// ✅ Bon : Plus simple et clair
bool EstAdulte(int age) => age >= 18;

Avantages du Clean Code

Facilité de lecture : Un code propre est plus facile à comprendre.
Moins de bugs : Un code clair réduit les erreurs.
Facilité de maintenance : Les futurs développeurs comprendront plus vite.
Évolutivité : Un bon design facilite l'ajout de nouvelles fonctionnalités.


Conclusion

Le Clean Code, c’est avant tout un état d’esprit :

  • Écrire du code pour les humains, pas seulement pour la machine.

  • Se poser la question : "Est-ce que je comprendrai ce code dans 6 mois ?"

  • Suivre les principes : lisibilité, simplicité, modularité, maintenabilité.

En appliquant ces bonnes pratiques, ton code deviendra plus propre, plus efficace et plus agréable à travailler. 🚀


=========================================================

=============================


### Principes de base du Clean Code :

1. Lisibilité :

- Le code doit être facile à lire et comprendre. Un autre développeur (ou vous-même dans quelques mois) doit pouvoir rapidement saisir ce que fait le code sans avoir à lire des commentaires complexes.

2. Simplicité :

- Éviter la complexité inutile. Un code simple est plus facile à maintenir, à déboguer et à faire évoluer. La simplicité ne veut pas dire sacrifier l’efficacité, mais plutôt éviter des structures trop complexes ou des abstractions inutiles.

3. Nommage explicite :

- Les noms des variables, des fonctions, et des classes doivent être clairs et explicites, décrivant bien leur rôle. Par exemple, `getTotalPrice()` est plus clair que `getTP()`.

4. Small Functions (Fonctions courtes) :

- Les fonctions doivent être courtes et ne faire qu'une seule chose. Si une fonction fait trop de choses, elle devient difficile à tester, à comprendre, et à maintenir. Un principe important est **"Do One Thing"**, chaque fonction doit avoir une seule responsabilité.

5. Responsabilité unique (SRP - Single Responsibility Principle) :

- Chaque classe ou fonction doit avoir une seule responsabilité ou un seul but. Cela permet de maintenir la modularité du code et d'éviter les dépendances indésirables.

6. Code auto-documenté :

- Le code bien écrit ne nécessite pas de nombreux commentaires pour être compris. Si le code est suffisamment clair, les commentaires deviennent souvent superflus. Cependant, s'il y a des logiques complexes, quelques commentaires pertinents peuvent être utiles.

7. Refactoring constant :

- Le code doit être continuellement amélioré et remanié pour rester propre. Il s’agit d’améliorer la structure du code sans modifier son comportement extérieur.

8. Respect des conventions de codage :

- Suivre les conventions du langage ou du projet est essentiel pour maintenir la cohérence. Chaque langage a ses propres bonnes pratiques (indentation, structure, organisation du code).

9. Privilégier la composition à l’héritage :

- En général, il est préférable d’utiliser des objets composés pour ajouter des fonctionnalités plutôt que d’utiliser l’héritage, qui peut rendre le code plus difficile à maintenir et à faire évoluer.

10. Gérer correctement les erreurs :

- Les erreurs doivent être gérées de manière claire et concise, en évitant les comportements silencieux ou les erreurs cachées. Utiliser des exceptions, des validations d’entrée et des tests pour éviter les erreurs inattendues.

### Spécificités et bonnes pratiques du Clean Code :

#### 1. Nommage de Variables et Fonctions :

- Clarté : Choisissez des noms significatifs et prononçables (par exemple `accountBalance` plutôt que `aB`).

- Descriptive : Un nom de fonction doit indiquer clairement ce qu’elle fait (par exemple, `calculateInterest()` est mieux que `doWork()`).

- Pas de commentaires inutiles : Si une fonction ou une variable est bien nommée, les commentaires redondants deviennent inutiles.

#### 2. **Fonctions courtes :**

- Essayez de limiter la taille des fonctions à environ **5-10 lignes**.

- Chaque fonction doit avoir **une seule responsabilité**.

- Les noms des fonctions doivent refléter leur comportement sans ambiguïté.

#### 3. **Commentaires pertinents :**

- Utilisez les commentaires uniquement lorsque cela est absolument nécessaire. Le code doit être **auto-descriptif**.

- Les commentaires doivent expliquer le "pourquoi" du code, pas le "quoi". Le code doit déjà être explicite sur ce qu'il fait.

#### 4. **Utiliser des objets et des structures de données appropriées :**

- N’utilisez pas de structures complexes si des structures simples peuvent faire l’affaire. Par exemple, n’utilisez pas une `HashMap` complexe si une simple `ArrayList` suffit.

- Ne dupliquez pas de code, utilisez des abstractions et des méthodes réutilisables.

#### 5. **Tests unitaires :**

- Un code propre est souvent associé à un code bien testé. Les tests unitaires permettent de vérifier que chaque composant fonctionne indépendamment et facilitent le refactoring.

- Suivre le principe **TDD (Test-Driven Development)** peut également contribuer à améliorer la qualité et la structure du code.

#### 6. **Éviter les dépendances cachées :**

- Évitez de créer des fonctions ou des classes qui dépendent implicitement d'autres parties du code. Toute dépendance doit être explicite.

#### 7. **DRY (Don’t Repeat Yourself) :**

- Ne dupliquez pas le code. Si vous trouvez que vous répétez du code similaire à plusieurs endroits, il est probable qu'une abstraction (une fonction ou une classe commune) soit nécessaire.

#### 8. **Gestion des exceptions claire :**

- Les exceptions doivent être gérées avec soin et précision. Évitez les blocs `try-catch` trop larges ou les messages d'erreur peu descriptifs.

Quelques règles supplémentaires issues du livre "Clean Code" :

- Fonctions de niveau abstrait constant : Toutes les instructions dans une fonction doivent être au même niveau d'abstraction. Si vous avez du code de bas niveau (comme des détails d'implémentation) mélangé avec du code de haut niveau (comme une vue globale), le code devient plus difficile à lire.

- Ne pas utiliser de "flag" dans les paramètres : Les paramètres booléens qui activent des comportements spécifiques d'une méthode indiquent souvent que cette méthode fait trop de choses.

### Exemples de Clean Code :

```java

// Mauvais exemple

int d; // nombre de jours

// Clean code

int daysSinceCreation;

```

```java

// Mauvais exemple

public void saveUser(User user) {

if (user.isValid()) {

// Sauvegarde de l'utilisateur

}

}

// Clean code

public void saveUser(User user) {

validateUser(user);

// Sauvegarde de l'utilisateur

}

```

### Conclusion :

Le Clean Code est un ensemble de pratiques qui visent à rendre le code plus maintenable, lisible, et modulaire. Il s'agit d'une approche qui fait partie de l'ingénierie logicielle de qualité et est essentielle dans des environnements de développement à long terme où de nombreux développeurs travaillent sur le même projet. En respectant ces principes, vous facilitez la collaboration entre les développeurs et assurez la pérennité de votre code.

Aucun commentaire:

Enregistrer un commentaire

Clean Code Lượt xem: