IFT3913
Qualité du logiciel et métriques
TP2
Conception et implantation d’un parseur
présenté à M. Sahraoui Houari
par
Nicola Grenon
GREN30077303 (grenonni)
le lundi 19 mars 2007
Introduction
À partir du parseur de données dws que nous avions créé dans un premier temps, nous avons maintenant mis en place un mécanisme d'évaluation de métriques associés à cette structure de données. Les valeurs ainsi calculées sont accessibles au moyen de l'interface graphique de même qu'au moyen de fichiers CVS générés par l'utilisation du bouton CVS de ladite interface.
Dans ce document sont expliquées les étapes de la réalisation en terme de méthode de travail de même que la schématisation de la relation interclasses servant à la manipulation des données.
Utilisation
Fichiers fournis: parseur.java [ Le fichier exécutable (main) + outils de parsing ]
Syntaxe.Java [ Les classes associées à la syntaxe à traiter ] S'y retrouve aussi le calcul des métriques
Fenetre.java [ Les détails de l'interface visuelle complémentée ]
Compilation: make
Exécution: java parseur
Après le lancement de l'application, il suffit d'entrer le nom du fichier à lire, puis de cliquer sur le bouton Load. Les divers champs des trois premières colonnes seront alors peuplés et sujets à changer dynamiquement selon les choix effectués par la suite dans ces derniers, reflétant ainsi les relations entre les champs.
Pour ce qui est du calcul des métriques, ceux-ci sont listés dans la colonne de droite. Il suffit (une fois un Schema chargé) de cliquer sur le libellé d'un de ces métriques pour que son évaluation soit affichée tout au bas de la colonne.
Finalement, à l'appui du bouton CSV, un fichier nommé nomduschema.csv sera généré.
Discussion
Tout d'abord un bref retour sur le TP1 pour signaler au correcteur que l'erreur qui a causé la perte de tant de points au niveau de la capacité de lire d'autres fichiers sources était un simple oubli d'une ligne qui hardcodait le nom du fichier à lire dans la phase initiale de développement. Cet oubli bénin a camouflé le fait que j'aurais dû filtrer les \n et les \t du fichier à lire. Somme toute donc, en retirant cette ligne en dur de même qu'en ajoutant un simple .replace('\n',' ').replace('\r',' ').replace('\t',' ') en un seul endroit, tous les problèmes furent réglés. C'est donc un code de parsing débogué qui est maintenant employé.
Pour ce qui est du TP2 maintenant, il est à noter que comme la conception de base du programme rendait aisée l'accès aux informations liées aux listes de clés et/ou de tables, il a été relativement facile d'intégrer les nouvelles fonctionnalités. Mis à part quelques méthodes d'accès qui ont dû être ajoutées aux classes définissant les structures, il a simplement suffit de faire ressortir les nombres disponibles.
En fait, 3 des métriques demandées ne nécessitaient qu'une seule ligne de code, tandis que les 4 autres se calculaient aisément au moyen de deux instructions principales, dont une simple boucle for.
Pour ce qui est du choix de la manière d'implémenter ces calculs, j'ai tenté de conserver une modularité au code en mettant dans une classe à part simplement la liste des algorithmes d'évaluation. Ils pourraient certes être intégrés directement à la structure de donnée (donnant la responsabilités aux classes propres de conserver les comptes et d'effectuer les calculs vis-à-vis leur dépendants), mais ce choix me semblait peu probant vu leur simplicité et le fait qu'en évitant ceci, je pouvais facilement réutiliser tout le code existant sans y apporter de réels changements, tout en n'affectant pas la performance de l'exécution du programme par la suite.
Au niveau de l'interface visuelle, il a suffit d'ajouter un «volet» qui permet de demander d'un simple clic sur le nom du métrique voulu l'obtention de l'information souhaitée. Le mécanisme fait le calcul sur demande, ce qui laisse la porte ouverte à un ajout de dynamisme dans l'application, par exemple en calculant d'autres métriques, mais seulement sur une table sélectionnée, etc.
Diagramme
Le diagramme des classes associées aux éléments de la structure de données est le même qu'au TP1, quoi que corrigé ici pour montrer les agrégations et complété de quelques méthodes peu significatives. Comme le calcul des métriques vient se greffer à celles-ci comme un add-on sous forme d'une classe entièrement static, il n'y a pas de lien direct avec les classes de la structure. (Il n'y a pas de nouvel objet généré!)
Schema identifier:String
+id()
+getArrayStar()
Star
+id() +getFact +getVectDim() +getArrayDim()
Fact identifier:String items:Vector<String>
+id()
+getArrayClef() +nombreItems()
Dimensional identifier:String items:Vector<String>
frequence:integer
+id()
+getArrayClef() +nombreItems() +ref()
+pop()
Clef identifier:String
+id() +setPrimary() +getPrimary()
1 1..n 1 1
1..n
1..n
1
0..n
1..n 1
Conclusion
Le calcul des métriques dans ce contexte-ci n'était certes pas un exploit. La plupart des calculs ne nécessitant qu'un simple renvoi (return) ou sinon une mince boucle additionnant les valeurs accumulées. J'en viens à me dire que si somme toute le travail n'était pas complexe, je peux à tout le moins affirmer que la structure développée pour sous-tendre la structure de données était manifestement adéquate vue la facilité avec laquelle j'ai pu y greffer l'ajout demandé. Comme j'en ai glissé un mot précédemment, il y aurait sans doute eu d'autres manières de coder ces calculs, par exemple en intégrant profondément ces calculs dans le code des classes mêmes. Ce pourrait être utile, voire nécessaire dans des cas plus complexes de traitement, mais ici, tant qu'on n'a pas à évaluer autre chose que des dénombrements de base, l'idée de tout conserver dans une classe static rend la tâche vraiment simple et conserve au code sa modularité.
Dans le TP1, nous nous demandions comment allait évoluer ce programme dans le futur et cela laissait planer un doute sur la pertinence des choix ayant été fait. On a vu ici qu'ils étaient bons.
Ce qu'il resterait à ajouter à ce programme pour le rendre plus versatile serait de lui permettre de conserver en mémoire plus d'un schéma à la fois. Il faudrait principalement alors modifier les points d'attache static ayant été utilisés ici dans un souci de simplicité. On pourrait soit tout transférer en dynamique, ce qui demanderait beaucoup de code ou plus simplement ajouter une structure conservant au niveau static de la classe Schema la liste de ceux-ci.
Note au correcteur: SVP noter que le retard d'environ 48h pour la remise de ce travail a été discuté avec le professeur au préalable.