CSC 4102 – Introduction au génie logiciel pour applications orientées objet

Portail informatique

Séance 7 — TP : Qualité du code et idiomes JAVA

(Re-)Positionnement dans le dépôt Git de GitLab

Voici la procédure que nous proposons (dans tous les cas « par défaut »). « En cas de panique », veuillez vous reporter à celle qui suit celle-ci.

  • Procédure « repositionnement »
    • on repart d'un dépôt mis à jour et on continue dans la branche develop
      • cd ~/CSC4102
        cd csc4102-projet
        git fetch # prendre connaissance des nouveautés
        git branch # quelle est la branche courante ?
        si pas déjà dans la branche develop alors « git checkout develop » # se positionner dans la branche
        git pull origin develop # accepter les modifications de la branche
        si conflit et besoin d'une fusion, « git mergetool --tool=meld » puis « git commit »

« En cas de panique », veuillez suivre la procédure qui suit :

  • Procédure « nouveau clonage »
    • on clone à nouveau le dépôt et on continue dans la branche develop :
      • cd ~/CSC4102
        mv csc4102-projet csc4102-projet_old # garder une copie au cas où du contenu n'ait pas été poussé
        git clone URL_DE_VOTRE_PROJET
        cd csc4102-projet
        git checkout develop # positionnement dans la branche develop
En fin d'énoncé de ce TP, nous proposons une procédure pour la tâche duale consistant à clore une phase de travail en validant et poussant les modifications sur le dépôt Git de GitLab.

Évaluation de la qualité du code : apprentissage et mise en place

  • analyse des éléments de code avec SpotBugs,
  • analyse des classes () et () pour notamment y ajouter les commentaires Javadoc.

Vérification de l'installation des greffons SpotBugs et Checkstyle

Reportez-vous à la page des Installations et configurations logicielles qui étaient à faire avant le démarrage du module, Étape 2.f « Programmation avec l'environnement Eclipse ».

Résolution des bugs trouvés par SpotBugs

Dans le menu contextuel du projet ou d'une classe dans l'explorateur, sélectionnez SpotBugs > Find Bugs. Eclipse vous propose d'ouvrir la perspective Bug Explorer. Les bugs sont repérés dans les classes par des icones : , , etc. Pour avoir des explications, cliquez sur les bugs ; Eclipse donne des informations dans la vue Bug Explorer.

À tout moment, vous pouvez retirer les marques d'analyse de SpotBugs avec le menu contextuel en sélectionnant SpotBugs > Clear FindBugs violations.

(Optionnel) Vous pouvez configurer le greffon pour « durcir » la détection. Opérez alors comme suit :

  • dans Eclipse, menu Window > Preferences > Java > SpotBugs,
  • puis, dans la fenêtre ouverte, vous pouvez régler le potentiomètre « Minimum rank to report » pour être plus exigeant en déplaçant le curseur vers 20.

Nous vous proposons le fonctionnement suivant pendant le travail en présentiel :

  • laisser ou ramener le potentiomètre « Minimum rank to report » à la valeur initiale (par défaut) du greffon, c'est-à-dire à 15 ;
  • résolvez tous les bugs dans une première étude de votre code, mais sans rester trop longtemps sur l'un d'eux ;
  • lorsque l'encadrant ou encadrante est disponible, soumettez ceux que vous n'arrivez pas comprendre ou à résoudre (en restant raisonnable sur la quantité) ;
  • en fin de TP, indiquez sur le bilan d'auto-évaluation les bugs (classe, numéro de ligne) qui vous posent problème (uniquement ceux pour lesquels vous êtes bloqués et en restant raisonnable sur la quantité).

Écriture des commentaires Javadoc des classes () et (), et respect d'un standard de codage avec CheckStyle

Les standards de codage disponibles dans Eclipse pour CheckStyle sont très pointilleux. Si vous les utilisez directement, vous aurez beaucoup/trop d'adaptations à faire dans votre code. Aussi, nous proposons une configuration pour CSC4102.

Pour voir la différence, commençons par vérifier le style de notre code avec la configuration de base des codes JAVA de Sun (société qui a créé le langage JAVA avant d'être absorbée par Oracle) :

  • dans Eclipse, menu Window > Preferences > Checkstyle,
  • puis, dans la fenêtre ouverte, sélection de la configuration « Sun Checks » avec Set as Default et Apply and Close,
  • et ensuite, dans le projet, sur src/main/java, menu contextuel Checkstyle > Check code with Checkstyle.

Le résultat est éloquent : il y a plusieurs centaines de corrections à opérer pour que le code dans src/main/java fourni au départ du module soit acceptable pour Oracle. Avec le style de Google, le nombre explose avec plus de mille défauts.

Nous fournissons une configuration adaptée à notre utilisation de JAVA en enseignement : par exemple, nous autorisons les tabulations pour l'indentation, les caractères «˽» en fin de ligne, les caractères «_» dans les noms des paquetages, les lignes a plus de 80 colonnes, etc. Cette configuration est disponible en deux versions, selon la version Eclipse utilisée (en fait la version du greffon Checkstyle) ; téléchargez le fichier pour votre IDE :

Dans Eclipse, choisissez la configuration que nous vous proposons comme configuration par défaut pour l'analyse de votre code : menu Window > Preferences > Checkstyle puis

  • création d'une nouvelle configuration avec New, choix de External Configuration File et Browse pour chercher le fichier téléchargé ; donnez un nom à cette nouvelle configuration (p.ex. « tsp-csc ») et validez avec OK ;
  • choix de la configuration « tsp-csc » comme configuration à utiliser par défaut en sélectionnant la configuration et cliquant sur Set as Default ;
  • effacement des violations précédemment détectées par le menu contextuel Checkstyle > Clear Checkstyle violations ;
  • vérifiez à nouveau votre code avec la nouvelle configuration : si vous obtenez un message d'erreur du style « Checkstyle execution failed due to an internal error » alors essayez le fichier de configuration suivant.

Si aucune des trois versions ne fonctionne, merci de nous le signaler en précisant la version de l'IDE.

documenter du code et respecter un style de codage est consommateur de temps, surtout quand on le fait après coup. Nous proposons de ne le faire que pour les classes () et (). Pour le dire à Checkstyle, dans toutes les classes autres que () et (), y compris dans les classes de tests, insérez au début de chacune de ces classes la ligne de commentaire suivante : « // CHECKSTYLE:OFF ».

Écrivez les commentaires Javadoc (documentation de référence) et résolvez les violations de style signalées. Pour ajouter un commentaire à un élément (classe, attribut ou méthode), positionnez le curseur sur l'élément et utilisez le menu Eclipse Source > Generate comment. Pour résoudre les alertes de violation de style, suivez globalement le même fonctionnement que pour SpotBugs : première étude, aide de l'encadrant ou de l'encadrante si besoin, etc.

À tout moment, et plus particulièrement avant de ré-exécuter Checkstyle, vous pouvez retirer les marques d'analyse de CheckStyle avec le menu en sélectionnant CheckStyle > Clear CheckStyle violations.

Lorsque vous avez écrit la documentation Javadoc des classes () et (), générez la documentation avec Eclipse : menu Project > Generate Javadoc. Ouvrez via l'explorateur du contenu de votre projet le fichier HTML ayant pour nom ./doc/index.html.

Félicitations !
Dorénavant,
(1) votre code doit être formatté correctement (menu Source > Format),
(2) Checkstyle doit être activé (menu Project > Properties > Checkstyle et Checkstyle active for this project),
(2) SpotBugs doit être activé (menu Project > Properties > SpotBugs et Run automatically).

Idiomes JAVA

  • programmer, si ce n'est pas déjà fait, des méthodes equals, hashCode, et toString,
  • utiliser les streams dans la programmation de certaines méthodes.

Méthodes equals et hashCode

Faites la liste des classes dont les objets sont dans des collections et/ou servent de clés pour des collections.

Pour chacune de ces classes, générez avec Eclipse le couple de méthodes equals et hashCode : menu Source > Generate hashCode and equals, et suivez l'assistant. Dans l'assistant, nous proposons de cocher les trois options suivantes :

  1. Use of `instanceof' to compare types,
  2. Use blocks in `if' statements, et
  3. Use `Objects.hash' and 'Objects.equals' methods (1.7 or higher).

dans l'assistant, portez votre attention sur le choix des attributs (consituant « la clef primaire ») de la classe : cf. la propriété « consistent » de la diapositive « 4.1 Méthode equals » du cours.

Méthodes toString

Pour toutes les classes, générez avec Eclipse une méthode toString : menu Source > Generate toString, et suivre l'assistant.

Portez une attention particulière aux associations bidirectionnelles : consultez la diapositive « 4.3.1 Associations bidirectionnelles et toString » du cours.

Apprentissage des Streams

Les éléments qui suivent permettent d'apprendre à utiliser les Streams et Optional principalement en remplaçant ou complétant du code existant.

Voici un rappel des éléments qui peuvent servir de points d'entrée à votre réflexion plus particulièrement pendant cette séance, à retrouver dans le dépôt csc4102-exemples :

  • eu.telecomsudparis.csc4102.cours.seance7.*,
  • eu.telecomsudparis.csc4102.etudesdecas.mediathequeavecstreams.Mediatheque.

Nous rappelons aussi les pages de la documentation Javadoc qui peuvent service de points d'entrée à votre réflexion :

Utilisation des Streams dans votre projet


Voici quelques endroits où les Streams peuvent être utilisés à bon escient :

  1. pour lister les réseaux sociaux (dans la classe de la façade), les derniers messages non encore lus (dans la classe réseau social), etc. À partir de ce qui est proposé dans le squelette du code de départ pour lister les utilisateurs (dans la classe de la façade).
  2. lorsque vous aurez ajouté les notifications dans la séance 8, pour émuler la fin de journée Pour les tests, nous proposons d'ajouter un cas d'utilisation quelque peu factice qui émule la fin de la journée, ce pour provoquer la notification des messages pour les utilisateurs ayant choisis la stratégie de notification « quotidien ». Par exemple, vous pourriez, dans la façade, parcourir la collection des réseaux sociaux, et vous pourriez, dans la classe réseau social, donc pour chaque réseau social, parcourir les participations des membres afin de sélectionner celles avec la stratégie de notification « quotidien », pour ensuite parcourir les messages reçus « aujourd'hui », c'est-à-dire après l'instant LocalDateTime.now().with(LocalTime.MIN).toInstant(ZoneOffset.UTC).

En un mot, démontrez que vous avez compris l'utilisation des pipelines des Streams en les utilisant à différents endroits dans votre code.

Utilisation de Optional dans votre projet


Dans cette étude de cas, nous ne proposons pas d'utilisation, par exemple dans la façade, de méthodes avec une valeur de retour de type Optional<T> autre que celles résultant de la manipulation des Streams.

Continuation du développement de l'application

dans cette section, nous présentons les éléments pour la seconde partie du module. Vous êtes en autonomie et devez lisser votre charge de travail sur les dernières séances. En termes de priorité, les remarques faites lors des suivis sont prioritaires.

Vous devez compléter votre logiciel pour qu'il possède toutes les fonctionnalités présentées dans le cahier des charges (cf. la section « Complétude du logiciel » du cahier des charges). Hormis la notification avec le patron de conception Publier/Souscrire, tout le logiciel peut être développé : pour la partie notification, si vous n'avez pas inséré le patron de conception Publier/Souscrire, utilisez un affichage à la console pour indiquer qu'un acteur est notifié.

Nous conseillons de commencer l'étude de ces éléments une fois les cas d'utilisation («  »), («  »), et («  ») programmés et testés sans le mécanisme des notifications.

Comme vous avez gagné en autonomie, nous vous laissons organiser votre travail en présentiel et en hors présentiel tout au long des dernières séances. Bien sûr, n'hésitez pas à discuter de vos tâches et de votre solution avec vos responsables de groupe.

Lors des travaux à venir, des modifications peuvent impacter la modélisation existante : diagramme de cas d'utilisation, pré-/post-conditions, tables de décision des tests de validation, diagramme de classes, diagrammes de séquence, etc.

Pour les nouveaux cas d'utilisation, nous vous laissons décider ce que vous modélisez, la seule obligation étant de fournir les nouveaux élements suivants :

  • précondition et postcondition de («  ») ;
  • tables de décision des tests de validation de («  ») ;
  • programmation du cas d'utilisation («  ») ;
  • programmation des tests de validation du cas d'utilisation («  »).

(Optionnel) Configuration de l'intégration continue avec GitLab CI

Rappels sur l'intégration continue avec GitLab CI

L'intégration continue consiste à exécuter via la forge logicielle des scripts de vérification que le code poussé n'introduit pas d'erreur. Dans notre cas, nous sommes intéressés par la compilation Maven, voire l'exécution des tests aussi avec Maven, voire même la vérification du code avec Checkstyle, toujours avec Maven. Nous ne proposons pas d'inclure SpotBugs dans l'intégration continue.

GitLab Continuous Integration (GitLab CI) propose un moyen de configuration simple via l'ajout d'un fichier « .gitlab-ci.yml » à la racine du dépôt Git. Vous avez déjà un tel fichier. Dans la configuration courante, seule la compilation Java est effectuée. D'ailleurs, vous avez peut-être déjà reçu un ou des courriels ayant pour sujet « csc4102-projet | Pipeline #numéro has failed for nom_branche | SHA1 du commit » lorsque le code que vous poussez ne compilait pas.

La commande mvn du job1 ci-dessous exclut les tests (la compilation via l'option -Dmaven.test.skip=true et l'exécution via l'option -DskipTests), la génération Javadoc (via l'option -Dmaven.javadoc.skip=true), et la vérification du code avec Checkstyle (via l'option -Dcheckstyle.skip).

Dans GitLab, comme le montrent les deux images qui suivent, vous pouvez voir le résultat d'un push suivi d'une compilation en erreur. L'image de gauche montre la liste des instantanés avec une croix rouge pour ceux en erreur. L'image de droite montre une exécution en erreur à cause d'une exécution Maven. Notez que GitLab CI récupère la dernière version de votre dépôt, se positionne sur l'instantané poussé (ici un instantané de la branche main) et exécute le script indiqué dans le fichier .gitlab-ci.yml avec la commande mvn.

 

Activation de la compilation et de l'exécution des tests

Dans le fichier .gitlab-ci.yml, retirez les options d'inhibition de la compilation et de l'exécution des tests. Ensuite, poussez la modification du fichier .gitlab-ci.yml et regardez dans GitLab pour vérifier que tout s'est bien déroulé.

(optionnel) Activation de l'exécution des tests et des vérifications Checkstyle lors de l'intégration continue

Dans le fichier .gitlab-ci.yml, selon vos souhaits, vous retirez l'option d'inhibition de la vérification de votre code avec Checkstyle. Faites attention aux guillemets anglaises (caractères « " ») à la fin de la commande du job.

(optionnel et beaucoup plus ambitieux) Activation de la génération de la documentation Javadoc

Si vous vous décidez à faire la documentation de toutes vos classes, vous pouvez retirer aussi l'option d'inhibition de la génération de la documentation Javadoc.

Mise à disposition du travail effectué dans le dépôt Git de GitLab

Systématiquement, avant de terminer une séance de travail, que ce soit en salle TP ou chez vous, mettez à jour votre dépôt local (au cas où vous ayez travaillé en parallèle), validez et poussez votre travail :

  • git fetch # charger les modifications non encore connues localement
    git pull origin develop # mettre à jour votre branche develop
    et si conflit et besoin d'une fusion, git mergetool --tool=meld
  • git status # connaître l'état de votre arborescence
    selon les besoins, pour préparer la zone de transit pour la validation du prochain instantané, git add, git mv, git checkout --, etc.
    git commit -m "je dis ce que contient le nouvel instantané" # valider les modifications de la zone de transit
    git push origin develop# pousser pour mettre à disposition
  • connectez-vous à GitLab et vérifiez que votre travail a été poussé.

À LA FIN DU TP DE LA SÉANCE

Avant de quitter le TP, veuillez s'il vous plaît remplir dans la page Partage de votre groupe le tableau d'avancement de votre binôme-projet :

C'est aussi le moment de parcourir la grille d'auto-évaluation de la séance.