Définissez des fonctions de qualité
Comment écrire des fonctions de qualité ? Il faut à la fois concevoir efficacement les composants de votre code et identifier clairement les éléments.
Mais commençons par le début : quand utiliser une fonction ? Voici quelques conseils à suivre :
Premièrement, si vous répétez au moins deux lignes de code, faites-en une fonction. Regardez l'exemple ci-dessous :
// Nourrir une personne
Console.WriteLine("Casser 2 œufs dans une poêle");
Console.WriteLine("Ajouter les légumes coupés");
Console.WriteLine("Remuer de temps en temps pendant 2 minutes");
// Nourrir une autre personne
Console.WriteLine("Casser 2 œufs dans une poêle");
Console.WriteLine("Ajouter les légumes coupés");
Console.WriteLine("Remuer de temps en temps pendant 2 minutes");
// OU
// Définir une fonction
public void FaireUneOmelette()
{
Console.WriteLine("Casser 2 œufs dans une poêle");
Console.WriteLine("Ajouter les légumes coupés");
Console.WriteLine("Remuer de temps en temps pendant 2 minutes");
}
// Nourrir une personne
FaireUneOmelette();
// Nourrir une autre personne
FaireUneOmelette();
Deuxièmement, si le code devient long et peu lisible, il est préférable de le placer dans une fonction, même s'il ne doit être exécuté qu'une seule fois. Si le contenu de votre fonction ne tient pas sur votre écran et que vous ne pouvez pas en suivre la logique d'un coup d'œil, c'est qu'il est probablement trop long. Si l'on devait fixer une limite arbitraire de longueur, on pourrait s'accorder sur 50 lignes :
// Un long morceau de code de plus de 50 lignes
// Remplacer par des fonctions
public void ExecuterLeDebut()
{
// 50 lignes de code ou moins
}
public void ExecuterLaFin()
{
// 50 lignes de code ou moins
}
ExecuterLeDebut();
ExecuterLaFin();
Enfin, si vous avez une fonction qui effectue plus d'une tâche, vous devez la diviser en plusieurs fonctions plus petites. Ensuite, créez une autre fonction globale qui appelle ces petites fonctions. Par exemple, vous avez besoin qu'une transaction de paiement fasse deux choses : enregistrer la transaction et notifier le système pour qu'il effectue les mises à jour correspondantes. On peut procéder comme suit :
public void Payer()
{
// Enregistrer la transaction
// Notifier le système
}
// Meilleure solution : la diviser en sous-fonctions
private void EnregistrerTransaction()
{
}
private void NotifierSysteme()
{
}
// Appeler les deux sous-fonctions
public void Payer()
{
EnregistrerTransaction();
NotifierSysteme();
}
On peut également classer les fonctions selon leur rôle :
Fonctions d'interface (comportement) : elles sont appelées par des éléments externes. La méthode
Payer
en est un exemple.Fonctions utilitaires : elles sont créées pour des raisons de commodité interne et de lisibilité. Les sous-fonctions créées dans le cadre de la fonction de traitement des paiements en sont un exemple.
Prenons un autre exemple en utilisant des objets voiture. Les fonctions d'interface sont les comportements qu'une classe doit implémenter pour une utilisation externe, par exemple :
Conduire
Tourner
Démarrer
Arrêter
Les fonctions utilitaires peuvent être :
CalculerVitesse
DemarrerMoteur
ArreterMoteur
Les fonctions d'interface doivent être suffisamment complètes pour utiliser tout le potentiel d'un objet. Les fonctions utilitaires ne doivent pas être visibles pour le code externe et doivent être bien organisées au sein de la classe.
Mettez en forme le code
La mise en forme joue un rôle important dans la qualité de votre code et peut être séparée en plusieurs éléments :
Le nommage
Les commentaires
Le style d'écriture
Chacun de ces éléments est important et doit faire l'objet d'une attention particulière.
Le nommage
Le nommage est l'un des composants essentiels d'un code de bonne qualité. Derrière ce terme se cachent deux actions distinctes :
Le choix du nom
Le respect des conventions de nommage
Trouver un nom de fonction n'a rien d'évident. Le nom que vous utilisez doit refléter l'objectif de votre fonction. Il doit décrire ce qu'elle fait.
Prenons l'exemple d'un objet voiture. Vous pouvez avoir une fonction appelée conduire
ou creerMouvementVoiture
. Vous pourriez aussi l'appeler bouger
, mais ce n'est pas assez clair.
Dans une classe qui génère des formes géométriques, vous pourriez avoir des fonctions de création de formes appelées creerCarre
ou creerRectangle
. Comme vous pouvez le constater, l'utilisation du préfixe creer dans cet exemple est plus appropriée que dans le précédent.
Le même concept s'applique au nommage des paramètres d'une fonction. Comme pour toute autre variable, le nom d'un paramètre doit indiquer son objectif :
public void Peindre(Voiture voiture, String couleur) // Recommandé
{
}
public void Peindre(Voiture v , String clr) // Déconseillé
{
}
De plus, il est important de respecter les conventions de nommage. Celles-ci dépendent du langage de programmation et de votre équipe de développement.
En C#, la convention de nommage à utiliser est la casse Pascal. Comme nous l'avons vu dans un chapitre précédent, le premier mot d'une fonction ou d'une classe commence par une majuscule. Le premier mot des noms de variables commence par une lettre minuscule.
public void DessinerForme() // Correct
{
}
public void dessinerForme() // Incorrect
{
}
Les commentaires
Les commentaires expliquent ce qui ne peut être compris en lisant le code. Ils peuvent également inclure quelques indications supplémentaires. Les exemples les plus courants sont les suivants :
Pourquoi : expliquer pourquoi une certaine approche d'implémentation a été choisie plutôt qu'une autre, surtout si l'autre semble être un choix plus judicieux.
Conseils : les indications supplémentaires peuvent mentionner les options disponibles dans la fonctionnalité de la classe utilisée depuis l'extérieur.
Il existe deux types de commentaires :
Les commentaires d'une seule ligne
Les commentaires de plusieurs lignes
Les commentaires d'une seule ligne sont définis par l'utilisation d'une double barre oblique //
au début du commentaire. Le reste de la ligne est considéré comme un commentaire :
// Commentaire d'une seule ligne
Ces commentaires sont utilisés pour des notes courtes. Si un commentaire occupe toute la largeur d'un environnement de développement typique, préférez-lui un commentaire de plusieurs lignes. L'utilisation de plusieurs commentaires d'une seule ligne convient lorsqu'ils sont contextuellement différents. Sinon, un seul commentaire de plusieurs lignes est plus approprié.
Définissez les commentaires de plusieurs lignes en utilisant les caractères d'ouverture et de fermeture /*
et */
:
/* Première ligne du commentaire de plusieurs lignes
Deuxième ligne du commentaire de plusieurs lignes
*/
Le style d'écriture
Le style d'écriture fait référence à la manière dont vous organisez votre code.
Il existe de nombreux cas de figure pour lesquels il n'y a pas de bonne ou de mauvaise pratique :
L'utilisation des espaces. Voici quelques exemples :
int a = 10;
a = a * 21;
// Commentaire
ou bien :
int a=10
a=a*21;
// Commentaire
Accolades sur la même ligne ou sur une nouvelle ligne :
if (true) {
}
else {
}
ou :
if (true)
{
}
else
{
}
Tabulations ou espaces pour mettre en forme le texte dans les fichiers.
Dans chacun de ces cas, les deux variantes sont acceptables et dépendent de votre équipe. En revanche, il est fortement déconseillé d'utiliser les deux dans le même projet. L'équipe doit adopter un style d'écriture unique suivi par tous ses membres. Cependant, il vous arrivera fréquemment de corriger et d'améliorer du code écrit par d'autres. Dans ce cas, il est préférable de suivre le style utilisé par les contributeurs précédents.
Testez par vous-même !
Prêt à coder ? Pour accéder à l’exercice, suivez ce lien.
En résumé
Dans ce chapitre, nous avons couvert les aspects fondamentaux de l'écriture d'un code de bonne qualité :
Les cas dans lesquels du code doit être transformé en fonction :
lorsqu'au moins deux lignes de code doivent être exécutées plus d'une fois ;
lorsqu'un fragment de code est trop volumineux pour tenir sur un écran ;
lorsqu'une fonction accomplit plusieurs tâches, utilisez des sous-fonctions utilitaires.
On distingue deux catégories de fonctions :
Les fonctions interfaces, qui exposent les méthodes de la classe en dehors de la classe.
Les fonctions utilitaires, qui sont utilisées dans une classe et qui améliorent l'architecture et la lisibilité.
La mise en forme joue un rôle clé dans la qualité du code. Elle comprend :
le respect des conventions de nommage ;
les commentaires ;
l'utilisation d'un style d'écriture cohérent.