Code propre en java Quelques règles de codage
Transcription
Code propre en java Quelques règles de codage
Code propre en java Quelques règles de codage Les pratiques actuelles du développement logiciel pointent l'importance de la qualité du code. La quête doit être de rendre tous les commentaires de description du code inutiles. Seuls les commentaires de documentation de bibliothèque de type API restent nécessaires. 1. Nommage 1.1 Nommage des identificateurs Mauvaise pratique 1 2 3 4 5 6 7 8 9 public List<int[]> getThem() { List<int[]> list1 = new ArrayList<int[]>(); for (int[] x : _theList) { if (x[0] == 4) { list1.add(x); } } return list1; } Bonne pratique 1 2 3 4 5 6 7 8 9 public List<Cell> getFlaggedCells() { List<Cell> flaggedCells = new ArrayList<Cell>(); for (Cell cell : _gameBoard) { if (cell.isFlagged()) { flaggedCells.add(cell); } } return flaggedCells; } 1.2 Éviter les caractères ambigus dans les noms Ne jamais utiliser la minuscule l ou la majuscule O comme nom de variable. Mauvaise pratique 1 2 3 4 5 6 int a = l; if (O == l) { a = 1; } else { l = 0; } École Nationale Supérieure d'Ingénieurs & Groupe de Laboratoires, C.N.R.S. 6, Boulevard Maréchal Juin, F-14050 CAEN cedex http://www.ensicaen.fr 2 ■ Code propre en java 1.3 Ne pas faire de jeu de mots L'humour est à manier avec précaution. En général si l'on relit des parties de code, c'est pour y trouver des bugs – si en plus il y a de l'humour douteux sur ces lignes cela peut énerver. Mauvaise pratique 1 int _pigeons = 0; // Les clients de l'entreprise 1.4 Utiliser des noms prononçables, mnémotechniques et partageables Mauvaise pratique 1 2 3 4 5 6 public final class DtaRcrd102 { private Date _genymdhms; private Date _modymdhms; private final String _pszqint = "102"; /* ... */ } ENSICAEN - Spécialité Informatique Bonne pratique 1 2 3 4 5 6 public final class Customer { private Date _generationTimestamp; private Date _modificationTimestamp; private final String recordId = "102"; /* ... */ } 1.5 Utiliser des noms recherchables Mauvaise pratique Ici 't' ne peut pas facilement être recherché dans le texte. 1 2 3 for (int j = 0; j < 34; j++) { s += (t[j] * 4) / 5; } Bonne pratique 1 2 3 4 5 6 7 8 9 int _realDaysPerIdealDay = 4; final int WORK_DAYS_PER_WEEK = 5; int _sum = 0; for (int j = 0; j < NUMBER_OF_TASKS; j++) { int realTaskDays = taskEstimate[j] * realDaysPerIdealDay; int realTaskWeeks = (realdays / WORK_DAYS_PER_WEEK); sum += realTaskWeeks; } Code propre en java ■ 3 1.6 Éviter les noms difficiles à différencier Mauvaise pratique 1 2 XYZControllerForEfficientHandlingOfStrings XYZControllerForEfficientStorageOfStrings 1.7 Éviter les noms avec encodage Mauvaise pratique La notation hongroise a été introduite lorsque les compilateurs ne faisaient pas de vérification d'équivalence entre les types. Aujourd'hui, elle rend le code illisible et non adapté à la maintenance. 1 2 3 unsigned int UIGetData() { … } Bonne pratique unsigned int getData() { … } Mauvaise pratique De plus, rien n'oblige à faire évoluer le nom de la variable avec la maintenance du code. Ici, le type de la variable phoneString est passé de String à int[] sans que le nom de la variable ait changé. 1 int[10] SPhoneNumber; 1.8 Utiliser une convention qui permet de distinguer les différents mots qui composent un nom En Java, on utilise la notation Camel Case. Mauvaise pratique 1 class vehicule_terreste{ } Bonne pratique 1 class VehiculeTerreste{ } 1.9 Nommage des attributs Les noms des attributs de classes doivent être privés et préfixés par le caractère '_'. Ceci permet de distinguer immédiatement un paramètre d'un attribut par son nom, d'éviter les problèmes de masquage de paramètres et d’éliminer les lourdeurs introduites par l'utilisation du mot clé this (this.attribut). La première lettre doit être une minuscule. ENSICAEN - Spécialité Informatique 1 2 3 4 ■ Code propre en java Mauvaise pratique 1 2 private String nom; private int volume; Bonne pratique 1 2 private String _nom; private int _volume; 1.10 Nommage des méthodes Les méthodes sont nommées avec un verbe ou une phrase intentionnelle (postPayment(), deletePage(), ou save()). Le nom doit commencer par une lettre en minuscule. Utilisez les standards get, set, et is pour les mutateurs et accesseurs. Bonne pratique 1 2 3 4 Artist artist = song.getArtist(); if (artist.isEmpty()) { song.setTag("Unknown artist"); } ENSICAEN - Spécialité Informatique 1.11 Nommage des paquets On utilise l'adresse Web de l'équipe de développement à l'envers. Puis, on y ajoute les noms de paquets du projet. Bonne pratique org.eclipse.swt.graphics fr.ensicaen.ecole.projet.model fr.ensicaen.ecole.projet.view 2. Conventions de codage 2.1 Indentation Pas de norme mais des standards propres à chaque entreprise. Voici les trois standards les plus utilisés : Indentation à la Pascal 1 2 3 4 5 6 7 8 9 int pascal( int p ) { if (test) { } else { } } Code propre en java ■ 5 Indentation à la Unix 1 2 3 4 5 int unix( int p ) { if (test) { } else { } } avec sa variante pour la déclaration des méthodes (p. ex. projet Linux) : 1 2 3 4 5 6 int unix( int p ) { if (test) { } else { } } Indentation à la C 1 2 3 4 5 6 int c( int p ) { if (test) { } else { } } Cette pratique introduit une lourdeur dans l'écriture. Mauvaise pratique 1 2 this.x1 = (-this.b + sqrt(this.b * this.b – 4 * this.a * this.c)) / 2 *this.a; Bonne pratique 1 _x1 = (-_b + sqrt(_b*_b – 4*_a*_c)) / 2*a; 2.3 Éliminer les instructions naïves Mauvaise pratique 1 2 3 if (boolean1 == true) { } else if (boolean2 == false) { } Bonne pratique 1 2 3 if (boolean1) { } else if (!boolean2) { } ENSICAEN - Spécialité Informatique 2.2 Ne pas précéder l'appel d'un attribut ou d'une méthode par 'this 6 ■ Code propre en java 2.4 Encadrer les instructions imbriquées par des accolades même s'il n'y a qu'une ligne Mauvaise pratique 1 2 for (int i = 0; i < 10; i++) tab[i] = i; Bonne pratique 1 2 3 for (int i = 0; i < 10; i++) { tab[i] = i; } 2.5 Remplacer les commentaires par du code Utilisez des variables ou des méthodes explicatives plutôt qu'un commentaire. Mauvaise pratique ENSICAEN - Spécialité Informatique 1 2 3 // does the module from the global list <module> depend on the // subsystem we are part of? if (smodule.getDependSubsystems().contains(module.getSubSystem())) {} Bonne pratique Le commentaire est donné par le nom de la variable : 1 2 3 ArrayList moduleDependees = smodule.getDependSubsystems(); String ourSubSystem = module.getSubSystem(); if (moduleDependees.contains(ourSubSystem)) { } Mauvaise pratique 1 2 3 4 // Check to see if the employee is eligible for full benefits if ((_employee.flags & HOURLY_FLAG) && (_employee.age > 65)) { /* ... */ } Bonne pratique Le commentaire est donné par le nom de la méthode : 1 2 3 4 5 6 if (isEligibleForFullBenefits()) { /* ... */ } final boolean isEligibleForFullBenefits() { return (_employee.flags & HOURLY_FLAG) && (_employee.age > 65) } 2.6 Remplacer les conditions complexes par une variable explicative Vous avez une expression de condition compliquée. Mauvaise pratique 1 if (platform.indexOf("MAC") > -1 Code propre en java ■ 7 2 3 4 5 && browser.indexOf("IE") > -1 && wasInitialized() && resize > 0) { // do something } Bonne pratique 1 2 3 4 5 6 boolean isMacOs = platform.indexOf("MAC") > -1; final boolean isIEBrowser = browser.indexOf("IE") > -1; final boolean wasResized = resize > 0; if (isMacOs && isIEBrowser && wasInitialized() && wasResized) { // do something } 2.7 Ne pas faire d'optimisation dans l'écriture du corps d'une méthode que le compilateur peut faire Mauvaise pratique 1 perimeter = 6.28 * radius; // 2.PI.R 1 perimeter = 2 * PI * radius; Mauvaise pratique 1 int x = y << 1; // x = y * 2 Bonne pratique 1 int x = y * 2; 2.8 Utiliser une ligne par déclaration de variable Mauvaise pratique 1 int a, b; Bonne pratique 1 2 int a; int b; 2.9 Remplacer un nombre magique par une constante symbolique Mauvaise pratique 1 2 3 double potentialEnergy( double mass, double height ) { return mass * 9.81 * height; } ENSICAEN - Spécialité Informatique Bonne pratique 8 ■ Code propre en java Bonne pratique 1 2 3 4 static final double GRAVITATIONAL_CONSTANT = 9.81; double potentialEnergy( double mass, double height ) { return mass * GRAVITATIONAL_CONSTANT * height; } 2.10 Supprimer les doubles négations Mauvaise pratique 1 if (!item.isNotFound()) { } Bonne pratique 1 if (item.isFound()) { } 3. Référence ENSICAEN - Spécialité Informatique Robert C. Martin, « Clean Code - A Handbook of Agile Software Craftsmanship », Prentice Hall, 2009. Martin Fowler, Refactoring « Improving the Design of Existing Code », Addison-Wesley Professional, 1999.