• Aucun résultat trouvé

Implémentation des classes du moteur de comparaison

4.2 Implémentation du système de comparaison structurelle

4.2.2 Implémentation des classes du moteur de comparaison

Au deuxième chapitre, l’algorithme général de la comparaison structurelle a été conçu, illus- tré par l’organigramme de la figure 2.11. Le but de cette partie consiste à reprendre cette concep- tion fonctionnelle pour concevoir le système d’un point de vue POO. Il s’agit d’élaborer le dia- gramme des classes intervenant dans ce système pour satisfaire le déroulement de l’algorithme. Il convient donc de répondre aux problèmes suivants :

• Parcours simultané des deux instances. • Comparaison des identifications. • Comparaison de l’état :

Attributs simples.

Attributs référençant des entités non identifiables (technique de hachage si nécessaire). • Comparaison de la position relative dans le graphe.

De plus, en utilisant une bibliothèque externe pour la gestion du modèle de données EX- PRESS, il n’est pas possible de modifier les classes existantes pour la gestion de chaque entité du modèle de données. Or, nous avons besoin d’ajouter de nouvelles opérations à ces entités, qui

consistent à les parcourir, les comparer et leur affecter des statuts de comparaison. Pour répondre à cette problématique, il existe une technique de conception informatique (Design Pattern en an- glais) : le visiteur [Gamma94]. Cette technique permet d’ajouter de nouveaux comportements à un ensemble de classes sans les modifier. Pour cela, cet ensemble de classes requiert seulement de supporter le mécanisme général des visiteurs. Il convient de préciser que ce mécanisme ne fonctionne qu’avec des modèles simples d’héritage (pas d’héritage multiple ni d’héritage AN- DOR). La version Express2LightCpp supporte cette fonctionnalité, contrairement au paquetage original Express2Cpp, car ce dernier gère tous les modèles d’héritage possibles.

Pour créer un visiteur, il suffit d’hériter de la classe ❱✐s✐t❡✉r, fournie par la bibliothèque associée au modèle de données. Ce nouveau visiteur possède alors une méthode par classe de cette bibliothèque, correspondant à l’application d’une fonctionnalité à cette classe. La corres- pondance entre la bibliothèque C++ et le modèle de données EXPRESS associé est telle qu’à une entité du modèle correspond une classe de la bibliothèque. De plus, le principe de sépa- ration des interfaces (Interface Separation Principle) [Martin96] déconseille l’utilisation d’une seule interface ou classe pour plusieurs fonctionnalités. Ce principe s’applique particulièrement aux visiteurs, car pour un visiteur, il n’existe qu’une méthode par entité du modèle de données EXPRESS.

C’est pourquoi nous avons choisi de séparer les fonctionnalités de notre système en plusieurs visiteurs. Une première catégorie de visiteurs représente les comparateurs. Dans cette catégo- rie, le visiteur analyse deux modèles d’ouvrages, représentés par deux ensembles d’instances de classes. Or, un visiteur « classique » opère sur un seul ensemble d’instances. Aussi un compara- teur possède-t-il une propriété♦r✐❣✐♥❛❧, qui représente l’instance en cours d’analyse du côté de l’instance originale. Le comparateur s’applique donc en tant que visiteur sur l’instance modifiée. Trois premiers comparateurs sont ainsi conçus :

1. ❙❡♠❛♥t✐❝❈♦♠♣❛r❛t♦r1 : à partir d’une entité de l’instance originale (propriété♦r✐❣✐♥❛❧) et d’une entité de l’instance modifiée (fournie en paramètre de ce visiteur), les méthodes de cette classe vérifient si ces entités ont déjà été visitées, comparent les identifications persistantes, et appellent le comparateur ❙t❛t❡❈♦♠♣❛r❛t♦r si les identifications corres- pondent.

2. ❙t❛t❡❈♦♠♣❛r❛t♦r : l’état des deux entités est comparé. Les méthodes de cette classe confrontent en particulier les attributs simples. Concernant les références aux entités non identifiables, il existe deux variantes que nous verrons plus loin.

3. ❈❤✐❧❞❈♦♠♣❛r❛t♦r : à partir des deux entités comparées s’effectue le parcours des entités enfants. Cette classe assure le parcours simultané des deux structures. Elle appelle ainsi le comparateur❙❡♠❛♥t✐❝❈♦♠♣❛r❛t♦r avec de nouvelles entités en paramètres. Par exemple, cette classe s’occupe de gérer le cas où certaines entités enfants sont référencées par des ensembles non ordonnés. Il convient alors de faire des tests d’identifications persistantes 1Il s’agit en fait d’un comparateur structurel, tant que les assistants sémantiques n’ont pas été implémentés. Mais

4.2. Implémentation du système de comparaison structurelle 119

pour envoyer les couples d’entités corrects (instance originale/instance modifiée) au visi- teur❙❡♠❛♥t✐❝❈♦♠♣❛r❛t♦r.

Il manque deux fonctionnalités à cette implémentation : la comparaison de la position rela- tive dans le graphe, et la comparaison d’entités non identifiables. Concernant le premier point, l’organigramme de la figure 2.11 (deuxième chapitre) suggérait d’effectuer cette comparaison juste après la comparaison d’états, pour chaque entité. En réalité, cette approche se révèle peu performante, car en mémoire, les entités du modèle d’ouvrage ne connaissent pas leurs entités parentes2. Pour chaque entité visitée, cela nécessiterait d’effectuer un parcours de toutes les entités susceptibles de référencer l’entité en cours. C’est pourquoi nous avons choisi une autre approche pour l’implémentation : au début de la visite d’une entité, au niveau du comparateur ❙❡♠❛♥t✐❝❈♦♠♣❛r❛t♦r, il est possible de connaitre l’entité parente qui référence l’entité en cours (via un paramètre supplémentaire fourni par❈❤✐❧❞❈♦♠♣❛r❛t♦r au ❙❡♠❛♥t✐❝❈♦♠♣❛r❛t♦r). Une référence à l’entité parente est sauvegardée pour l’entité en cours. Comme le parcours est ex- haustif, tous les liens sont parcourus, c’est-à-dire que chaque entité connait l’ensemble de ses parents, grâce à ces sauvegardes. Ainsi, la comparaison des positions relatives s’effectue à la fin du double parcours. Les couples d’entités reconnus (possédant donc le statut ’OK’ ou ’changé’) sont comparés grâce à cette nouvelle information.

Concernant le deuxième point sur la comparaison d’entités non identifiables, deux méthodes ont été étudiées. La première consiste à créer un comparateur dédié aux entités non identi- fiables :◆✐❞❈♦♠♣❛r❛t♦r (’Nid’ pour ’non identifiable’). Cette classe gère non seulement la com- paraison des attributs de ces entités, mais aussi le parcours des liens entre entités non identi- fiables. Après chaque comparaison de couples d’entités non identifiables, le résultat est sauvé, afin de ne pas effectuer une même comparaison plusieurs fois. Cela peut arriver si une entité non identifiable (un point 3D par exemple) est utilisée plusieurs fois par des entités identifiables.

La deuxième variante utilise la méthode de table de hachage. Cette technique a déjà été introduite au chapitre 2, à la section 2.4.2. Il s’agit de transformer n’importe quelle structure en un nombre entier, comme l’illustre la figure 4.5.

Si des entités non identifiables référencent d’autres entités identifiables via des attributs, le hachage devient récursif. Cependant, le risque d’utiliser une telle technique est le suivant : la ga- rantie que deux structures différentes génèrent deux hachages différents est seulement d’ordre statistique. En effet, il existe une infinité de structures alors que le nombre de hachages possible est fini. Le paradoxe des anniversaires indique que la probabilité d’une collision n’est pas négli- geable [Weisstein03]. Une formule permet de l’estimer : soit n le nombre d’entités susceptibles d’avoir un hachage. Soit d le nombre de valeurs possibles pour le hachage. La probabilité de collision est alors approximée par la formule suivante :

p(n, d) ≈ 1 − exp −n(n − 1) 2d



(4.1) Dans le cadre de nos travaux, les modèles d’ouvrage les plus volumineux possèdent moins de 400000 entités. En utilisant un codage sur 64 bits, on a alors n = 400000 et d = 264, d’où

2

p(n, d) ≈ 4.3.10−9. Nous avons donc choisi de garder cette technique.

L’implémentation d’une technique de hachage est simple, car de nombreuses bibliothèques sont disponibles pour offrir de telles fonctionnalités, comme Boost en C++ [James06]. Pour créer un hachage adapté à chaque entité non identifiable, un nouveau visiteur❍❛s❤✐♥❣❱✐s✐t♦r est réalisé.

Dans un premier temps, nous avons choisi la première variante de manière intuitive, l’idée des tables de hachage n’est venue que dans un deuxième temps pour améliorer les performances et simplifier le traitement. La figure 4.6 représente le diagramme global des classes intervenant dans cette implémentation, suivant le paradigme UML.

Ce système répond à toutes les fonctionnalités demandées. Cependant, conformément aux conclusions du chapitre 2, le moteur de comparaison a besoin d’informations spécifiques au modèle de données pour fonctionner : quelles sont les entités identifiables et leur attribut servant d’identification persistante ? Quelle est l’entité racine ? Pour résoudre ce problème, nous avons choisi d’intégrer un assistant structurel à l’implémentation existante.