CodeGym /Cours /C# SELF /Conseils de style et de lisibilité pour le code OOP

Conseils de style et de lisibilité pour le code OOP

C# SELF
Niveau 25 , Leçon 4
Disponible

1. Introduction

"Code propre" — ce n'est pas une vache sacrée, mais un vrai outil de survie pour les devs. Dans n'importe quel projet OOP, même le plus cool, tu te retrouves vite avec plein de classes, de champs, de méthodes, de liens chelous... Si tu casses l'esthétique et la structure, dans une semaine ton propre code devient un escape game impossible. Pour en savoir plus sur la "lutte pour la survie", check Robert Martin, "Clean Code" — c'est pile sur ce genre de batailles.

Le style dans le code — ce n'est pas "chacun fait comme il veut", c'est pour que tout le monde vive mieux :

  • Un collègue (ou toi-même) peut piger vite ce qui se passe.
  • Les bugs (surtout d'archi) se voient direct.
  • Le code est plus simple à faire évoluer, avec moins de boulettes.

Voyons comment faire du code OOP que les correcteurs, les collègues et même les linters vont kiffer.

2. Les noms : ta première ligne de défense

Nommer les classes

Les classes en C# se nomment en PascalCase (chaque partie du mot commence par une majuscule, genre : MyNewClass) et le nom doit répondre clairement à "Qu'est-ce que c'est ?". Les noms doivent être des noms communs !

public class CompteEtudiant { /* ... */ }
public class GenerateurFacture { /* ... */ }

Pas bien :

class faisDeLaMagie { ... } // Pas bien : quelle magie ? PascalCase non respecté.

Nommer les méthodes

Les méthodes — aussi en PascalCase, mais ici c'est mieux d'utiliser verbe + objet de l'action :

public void ImprimerRapport() { ... }
public string ObtenirNomFormate() { ... }

Les méthodes doivent refléter une action (Imprimer, Obtenir, Sauvegarder, Calculer, etc.), pour qu'à la lecture on pige direct ce qui va se passer.

Nommer les champs et propriétés

Les champs sont en général private, nommés en minuscule avec camelCase, souvent avec un underscore :

private int _compteur;
private Etudiant _proprietaire;

Les propriétésPascalCase, car elles font partie de l'interface publique de la classe :

public int Solde { get; set; }

Variables

Les variables localescamelCase, aussi court et clair que possible dans le contexte :

string nomSaisi;
int nombreEtudiants;

Et, s'il te plaît, les variables genre a1, result2, truc — c'est juste si tu veux te créer un escape game pour le mois prochain.

3. Organisation de la structure de la classe

Bien placer les membres d'une classe rend la navigation plus simple et aide à piger vite ce qui suit quoi.

En général on fait comme ça :

  1. Constructeurs
  2. Propriétés
  3. Méthodes
  4. Types imbriqués (enum, class, etc.)

Exemple :


public class Etudiant
{
    // --- Champs ---
    private string _nom;

    // --- Constructeur ---
    public Etudiant(string nom)
    {
        _nom = nom;
    }

    // --- Propriétés ---
    public string Nom
    {
        get => _nom;
        set => _nom = value;
    }

    // --- Méthodes ---
    public void AfficherInfo()
    {
        Console.WriteLine($"Nom : {_nom}");
    }
}

Ces "blocs" sont pratiques à séparer avec des commentaires (// --- Méthodes ---), surtout dans les grosses classes. JetBrains Rider, Visual Studio et d'autres IDE permettent de plier/déplier les sections vite fait.

4. Commentaires et documentation

Les commentaires, c'est cool. Mais c'est nul si tu en abuses ou si tu écris des "explications pour du code incompréhensible", alors que tu pourrais juste changer le code !

Un bon commentaire — c'est celui qui explique "pourquoi", pas "quoi".

// On utilise Guid comme identifiant unique car le système est distribué
public Guid Id { get; set; }

Documentation des méthodes, classes et propriétés

Utilise la doc xml pour les classes et les méthodes publiques. Les IDE vont afficher ces descriptions quand tu passes la souris dessus.


/// <summary>
/// Représente un étudiant de l'université.
/// </summary>
public class Etudiant
{
    /// <summary>
    /// Nom de l'étudiant.
    /// </summary>
    public string Nom { get; set; }
}

Ce qu'il NE faut PAS commenter

  • Les trucs évidents (i++ // on augmente i de 1).
  • Les variables mal nommées ("// ici il se passe un truc" — ouais, mais quoi ?).

5. Diviser pour mieux régner

Petites classes et méthodes

La règle d'or : une classe — une responsabilité (voir Principe de responsabilité unique). Si la classe Etudiant gère les notes, les emails et l'emploi du temps — y'a un souci.

  • Classes jusqu'à 300-400 lignes — ça va. Plus — pose-toi des questions.
  • Méthodes jusqu'à 15-20 lignes — c'est lisible. Sauf si c'est un gros handler de cas particulier.

Exemple d'une méthode "gonflée" :


public void Traiter()
{
    // Notification du client
    // Sauvegarder les changements
    // Envoyer un email
    // Écrire les logs
    // ... (15 étapes)
}

Mieux :


public void Traiter()
{
    NotifierClient();
    SauvegarderChangements();
    EnvoyerEmail();
    LoggerActivite();
}

Chacune des étapes est dans une méthode privée à part, le code est plus compact et plus facile à tester.

6. Astuces utiles

Structure visuelle : formatage, indentations, lignes vides

Les IDE savent formater le code tout seuls (Ctrl+K, D dans Visual Studio, Ctrl+Alt+L dans Rider), mais faut quand même connaître les bases.

  • INDENTATION — 4 espaces. Pas de tab, pas 2 espaces.
  • LIGNES VIDES — sépare les méthodes, les champs des propriétés, les propriétés des méthodes.
  • ACCOLADES toujours à la ligne pour les classes et méthodes (style Allman) :

public class Test
{
    public void Imprimer()
    {
        Console.WriteLine("Salut");
    }
}

Membres "forts" et "faibles" : modificateurs d'accès

Essaie toujours de tout fermer au max : n'ouvre que ce qui doit vraiment être accessible de dehors. Si un champ ou une méthode ne sert qu'en interne — mets-le en private. Seulement si les héritiers en ont besoin — protected. public — juste pour les contrats.

Pas bien :

public string ChaineConnexion; // N'importe qui peut la changer !

Mieux :


private string _chaineConnexion;
public string ChaineConnexion
{
    get => _chaineConnexion;
    private set => _chaineConnexion = value;
}

Utiliser les propriétés automatiques

Avec les propriétés automatiques et les setters init-only, écrire des propriétés "à la main" c'est devenu ringard.

Exemple :


public string Nom { get; set; } // Nickel !
public int Age { get; init; }    // Juste pour l'init, plus safe.

Et si tu veux des propriétés calculées :


public string NomComplet => $"{Prenom} {Nom}";

Encapsulation et getters/setters

Si une propriété a une logique métier pour la modification ou le contrôle, utilise un champ privé + getter/setter public avec la logique.


private int _note;
public int Note
{
    get => _note;
    set
    {
        if (value < 0) _note = 0;
        else if (value > 100) _note = 100;
        else _note = value;
    }
}

Comme ça, tu ne risques pas de "casser" l'objet par accident.

7. Encore des astuces utiles

N'aie pas peur des interfaces et des abstractions

Les interfaces servent à faire des contrats pratiques, à tester et à étendre l'appli.

Pas bien :

  • interface avec une seule méthode, jamais utilisée ;
  • interface implémentée par une seule classe.
Bien :
  • interface utilisée par 2 classes ou plus ;
  • interface pour abstraire des systèmes externes (genre pour le logging, la persistance de données).

Écris ton code pour qu'il soit facile à tester

Un signe d'un bon code OOP — c'est qu'il est testable.

  • Évite les méthodes qui dépendent de variables globales ou de champs statiques.
  • N'aie pas peur de l'injection de dépendances — via les paramètres du constructeur (Dependency Injection).
  • Sépare les calculs (la logique) et l'interaction utilisateur (input/output). Ça facilite non seulement les tests, mais aussi l'évolution de l'appli.

Lifehacks et anti-patterns pour débutants

  • N'écris pas de "classe Dieu" (God Object) qui fait tout.
  • N'utilise pas de "nombres magiques" sans explication (if (status == 42) — pourquoi 42 ?).
  • N'abuse pas de l'héritage juste pour faire de l'héritage — parfois la composition (une classe avec des champs d'autres classes, pas un héritier) c'est mieux.
  • N'écris pas de méthodes complexes de 100 lignes — c'est impossible à tester et à comprendre.
  • Laisse toujours la porte ouverte à l'extension (open/closed principle).

8. À quoi ressemblent un mauvais et un bon code

Mauvais exemple :


class e // Pas bien : nom de classe en minuscule.
{
    public int a; // inutile, nom pourri
    public void m() // Pas bien : méthode avec un nom d'une lettre.
    {
        Console.WriteLine(a);
        // Pas bien : on ne sait pas ce que fait la méthode.
    }
}

Bon exemple :


// Représente un étudiant.
public class Etudiant
{
    // Âge de l'étudiant.    
    private int _age;
    public int Age
    {
        get => _age;
        set => _age = value < 0 ? 0 : value;
    }

    // Affiche les infos de l'étudiant.
    public void AfficherInfo()
    {
        Console.WriteLine($"Âge de l'étudiant : {Age}");
    }
}
2
Mission
C# SELF, niveau 25, leçon 4
Bloqué
Nom correct des classes et des méthodes
Nom correct des classes et des méthodes
2
Mission
C# SELF, niveau 25, leçon 4
Bloqué
Organisation de la structure d'une classe
Organisation de la structure d'une classe
1
Étude/Quiz
Erreurs lors de l'héritage, niveau 25, leçon 4
Indisponible
Erreurs lors de l'héritage
Erreurs fréquentes lors de la déclaration des classes et des objets
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION