Académique Documents
Professionnel Documents
Culture Documents
Année : 2019/2020
MEMOIRE
Présenté en vue de l’obtention du Diplôme de Master
TITRE
L’Analyse de l’Historique d’Evolution de Logiciel
pour la Détection des Défauts de modularité
Filière
Informatique
Spécialité
Génie Logiciel
Par
YAGOUBI Wafia
Devant le jury
PRESIDENT: AMIRAT Abdelkrim PROF U.SOUK-AHRAS
EXAMINATEUR : MENASRIA Ahcen MAA U.SOUK-AHRAS
N°……./2020
Ce travail est l’aboutissement d’un dur labeur et de beaucoup
de sacrifices ; il n’a pu être mené à bien qu’avec le soutien de
plusieurs personnes que je voudrais, à travers ces quelques
lignes, remercier du fond du cœur.
Mes remerciements vont d’abord au Créateur de l’univers
qui m’a doté d’intelligence, et nous a maintenu en santé pour
mener à bien cette année d’étude.
Je tiens aussi à adresser mes remerciements à mes parents,
ma famille, et plus précisément à mes frères, mes beaux-frères
et mes sœurs qui m’ont toujours soutenu et poussé à continuer
mes études. Ce présent travail a pu voir le jour grâce à leur
soutien.
Je voudrai présenter mes remerciements à la directrice de ce
mémoire Dr « Hanane Cherait » pour l’orientation, la confiance,
la patience et surtout ses conseils judicieux, qui ont contribué à
alimenter ma réflexion et qui ont constitué un mémoire
considérable sans laquelle ce travail n’aurait pas pu être mené
au bon port.
Mon encadreur trouve dans ce travail un hommage vivant à
sa haute personnalité. Je voudrai également la témoigner ma
gratitude pour son soutien.
Je tiens à exprimer nos sincères remerciements à tous mes
professeurs qui nous ont enseigné et qui par leurs compétences
nous ont soutenu dans la poursuite de mes études. J’exprime
toute ma reconnaissance et gratitude à Mme le chef de
département Dr « Drissi Samia », à Mr le chef de spécialité
Dr « Noureddine Gasmallah » du département de
Mathématiques et Informatique et plus précisément de la
spécialité Master II « Génie Logiciel » et à l’administration
surtout Mme « Malika » pour leurs efforts à nous garantir la
continuité et l’aboutissement de ce mémoire.
Mes sincères remercîments s’adressent aussi à Monsieur le
président de jury pour m’avoir fait l’honneur de présider le jury.
Je tiens également à remercier les examinateurs de ce
mémoire pour m’avoir honoré de leur présence et accepté
de jury ce travail.
Enfin, on remercie tous ceux qui, de près ou de loin, ont
contribué à la réalisation de ce travail.
Dédicaces
Toutes les lettres ne sauraient trouver les mots qu’il faut …
Tous les mots ne sauraient exprimer la gratitude, l’amour, le respect, la reconnaissance…Aussi, c’est tout
simplement que je dédie ce travail…
Samia, Atef et ses enfants Feras et Baraa, à Mamin, Bessam, Latifa et son mari Said et leurs
enfants Djouri, Imed et Tasnim. A ma très chère tante Hakima. A ceux qui n’ont jamais cessé de
m’encouragé, me conseiller. A ceux qui n’ont jamais été avares ni de leur temps ni de leurs connaissances
pour satisfaire mes interrogations.
A mes chères amies
Pour m’avoir toujours accompagné.
Wafia
Résumé
L’objectif de l’analyse de l’historique d’évolution d’un projet logiciel est de déceler des dépendantes
logiques séduisantes et intéressantes entre ses artéfacts. Pour ce faire, l’analyse d’une seule version est
infaisable. C’est ainsi, que nous avons fondés sur ce genre de dépendances afin de proposer notre approche
d’analyse de la modularité de logiciels orientés objet (OO). Notre but est de savoir à quel point ce logiciel
est modulaire ? et de guider le développeur à prendre une décision si le logiciel nécessite une restructuration,
ou encore un refactoring pour l’obtention d’une version plus modulaire. Notre approche est subdivisée en
deux phases primordiales. Initialement, en vue de détecter les dépendances logiques entre ses classes et ses
packages, nous analysons le dépôt de versions de l’application OO. En appliquant l’algorithme Apriori sur
ces dépendances, des règles d’association seront générées à partir de ces dernières. Le résultat trouvé sera
entreposé dans une base de données (BDD). Secondement, notre outil « Logical Modularity Analyser »
intervient dans le but d’utiliser ces règles afin de mesurer la modularité du logiciel OO. Cet outil développé
depuis NetBeans va prendre en charge ces règles et génère des dépendances logiques interne qui représente
la cohésion et d’autres dépendances logiques externes décrivant le couplage. Ces dernières seront les
mesures à prendre en considération par le développeur. Dans notre étude, nous avons examinés les dépôts de
versions de trois les applications OO Open-source volumineuses dans le souci de démontrer la fiabilité, la
faisabilité et l’efficience de notre proposition.
4
Abstract
The objective of the analysis of the evolution history of a software project is to detect attractive and
interesting logical dependencies between its artifacts. To do this, the analysis of a single version is
impossible. Thus, we have based on this kind of dependencies in order to propose our approach to analyzing
the modularity of object-oriented software (OO). Our goal is to know how modular this software is? and
guide the developer to make a decision if the software requires restructuring, or even refactoring to obtain a
more modular version. Our approach is divided into two essential phases. Initially, in order to detect the
logical dependencies between its classes and its packages, we analyze the repository of versions of the OO
application. By applying the Apriori algorithm to these dependencies, association rules will be generated
from these dependencies. The result found will be stored in a database (BDD). Secondly, our «Logical
Modularity Analyser» tool intervenes in order to use these rules to measure the modularity of the OO
software. This tool developed with NetBeans will support these rules and generate internal logical
dependencies that represent cohesion and other external logical dependencies describing the linkage. These
two will be the measures to be taken into consideration by the developer. In our study, we examined the
version repositories of three large open-source OO applications to demonstrate the reliability, feasibility and
efficiency of our proposal.
Keywords: Software modularity, Evolution history, Version control system, Mining, Logical
dependency, Association rule, Apriori, NetBeans, Coupling, Cohesion.
5
تلخيص
إن الهدف من تحليل تاريخ تطور مشروع برمجي هو اكتشاف تبعيات منطقية مثيرة لالهتمام بين منتجاته .ولهذا فإن تحليل نسخة واحWWدة أمWWر
مستحيل .ومن هذا المنطلق ،قد قمنا باالستناد إلى هذا النوع من التبعيات من أجل اقتراح منهجنا في تحليWWل قابليWWة تعWWديل البرمجيWWات الموجهWWة
إلى الكائنات .هدفنا هو معرفة مدى تطبيق نظام الوحدات النموذجية لهذا البرنامج؟ وتوجيه المطور التخاذ قرار إذا كان البرنامج يتطلب إعادة
هيكلة أو حتى إعادة تحليل للحصول على إصدار أكثر نمطية .إن نهجنا ينقسم إلى مرحلتين أساسيتين .في البداية ،من أجل الكشف عن التبعي ات
المنطقية بين فئاته وحزمه ،نقوم بتحليل مستودع إصدارات تطبيق .OOومن خالل تطبيق خوارزمية Aprioriعلى هذه التبعيات ،س يتم إنش اء قواع د
االقتران من هذه التبعيات .سيتم تخزين النتيجة التي تم العثور عليها في قاعدة بيان ات ( .)BDDثاني ا ،أداة "محل ل النمطي ة المنطقي ة" تت دخل من أج ل
استخدام هذه القواعد لقياس قابلية تعديل برنامج .OOوستدعم هذه األداة التي تم تطويرها باستخدام NetBeansهذه القواعد وستنش ئ تبعي ات منطقي ة
داخلية تمثل التماسك والتبعيات المنطقية الخارجية األخرى التي تصف االرتباط .وسيشكل هذان المعياران الذان يتعين على المطور أخ ذها في االعتب ار.
في دراستنا ،قمنا بفحص مستودعات إصدار ثالثة تطبيقات OOكبيرة المساحة مفتوحة المصدر لتوضيح موثوقية اقتراحنا وجدواه وكفاءته.
: Keywordsنمطية البرمجيات ،تاريخ التطور ،نظام التحكم في اإلصدار ،التعدين ،التبعية المنطقية ،قاعدة االتحاد،Apriori، NetBeans ،
توصيل ،التماسك.
6
Table de matières
iii
Table de figures
Figure II-1: La modularité d’un système logiciel................................................................................8
Figure II-2: Spectre du degré de la cohésion. [PRE97].....................................................................13
Figure II-3: Couplage entre les modules............................................................................................14
Figure II-4:Types de couplage [YOU79]...........................................................................................15
Figure III-1: Conserver l’historique...................................................................................................29
Figure III-2:Travail collaboratif.........................................................................................................29
Figure III-3: Modèle des systèmes de contrôle de versions locaux...................................................30
Figure III-4:Modèle des systèmes de contrôle de versions centralisés..............................................30
Figure III-5:Modèle des systèmes de contrôle de versions distribués...............................................31
Figure III-6:Fonctionnalités de haut niveau d'un SCV [ALT09].......................................................33
Figure III-7: L’analyse de l’évolution du logiciel [CHE14]..............................................................36
Figure IV-1:Vue globale de notre approche......................................................................................49
Figure IV-2: Les étapes de la génération des dépendances logiques.................................................50
Figure IV-3: Extraction de données avec Git.....................................................................................50
Figure IV-4: Différenciation entre les versions.................................................................................51
Figure IV-5: Diagramme de classe de notre application....................................................................58
Figure IV-6: Diagramme de séquence générer les règles d’association............................................59
Figure V-1: Les étapes de génération des règles d'association..........................................................63
Figure V-2: La création de dépôt des transactions de changement en format XML.........................64
Figure V-3: Fenêtre principale de notre application..........................................................................69
Figure V-4: Interface de génération des règles d’association............................................................69
Figure V-5: Fenêtre représentant le couplage et la cohésion.............................................................70
Figure V-6: Les transactions de changement de l'application Traccar..............................................73
Figure V-7: Cohésion et couplage du logiciel Traccar......................................................................74
Figure V-8: Les règles d'association de l'application Bco.Bcozy......................................................76
Figure V-9: Cohésion et couplage du logiciel Bco.Bcozy.................................................................77
Figure V-10: Les règles d'association de l'application Teammates...................................................79
Figure V-11: Cohésion et couplage du logiciel Teammates..............................................................80
Figure V-12: Zoom-in du graphe des dépendances logiques de l'application Traccar......................81
iv
Listes des tableaux
v
Table des listings
vi
vii
CHAPITRE I
INTRODUCTION
GENERALE
1. Contexte de Travail
2. Problématiques et Motivations
3. Objectifs et Contributions
4. Contenu de mémoire
Chapitre I : Introduction Générale
CHAPITRE I
INTRODUCTION GENERALE
La complexité est le grand défi des développeurs. Elle peut évoluer de manière exponentielle avec la
taille du logiciel. Heureusement, la modularisation nous donne des super pouvoirs qui combattent la
complexité. Son principe consiste à décomposer de grands systèmes logiciels complexes en petites parties
gérables. Dans un système logiciel orienté objet (OO) par exemple, les classes jouent le rôle de modules qui
encapsule les méthodes et les variables. Pour les systèmes OO volumineux et complexes, un package peut
jouer le rôle d'un module qui regroupe un ensemble de classes collaboratrices pour fournir des services bien
identifiés au reste du système.
Avec une bonne conception modulaire, il n'y a pas de limite à la hauteur et à la portée du logiciel. Les
modules nous donnent la possibilité d'abstraire une complexité arbitraire derrière des interfaces propres et
simples. Il est même plus facile d'ajouter à un système logiciel des nouvelles fonctionnalités le long de son
évolution. Par conséquent, la modularité est considérée comme le facteur clés de succès de la conception de
logiciels. Elle a un impact significatif sur de nombreux attributs de qualité externes tels que la réutilisabilité,
la maintenabilité et la compréhensibilité de logiciel. Ainsi, proposer des techniques et des métriques pour
analyser et mesurer la modularité du logiciel est très important.
1
Chapitre I : Introduction Générale
systèmes logiciels afin de détecter les défauts de modularité possibles. Ce type d’analyse est très important
pour les développeurs, puisqu’il aide à localiser les parties du logiciel touchées par un défaut de modularité.
Ensuite, ils peuvent appliquer des techniques adéquates afin d’améliorer la conception en supportant
beaucoup plus la modularité.
Plusieurs travaux de recherche ont utilisé les relations statiques et sémantiques de logiciel pour analyser
sa modularité. Néanmoins, d’autres relations très intéressantes ne peuvent pas être détectées directement à
partir du code source (statiquement ou sémantiquement). De telles relations connues par « dépendances
logiques » ou « dépendances évolutionnaires » peuvent être extraites en analysant le dépôt de l’historique
de l'évolution du logiciel. L’idée consiste à extraire les dépendances cachées dans le dépôt de version i.e. si
deux artefacts logiciels sont souvent changés ensemble, donc il existe une dépendance logique entre eux.
Les dépendances logiques sont beaucoup plus intéressantes que les relations statiques et sémantiques
pour analyser le logiciel, puisqu’elles présentent réellement et explicitement les Co-changements entre les
artefacts logiciels i.e. les artefacts logiciels ont été changés pratiquement ensemble par le développeur.
Plusieurs travaux de recherche ont été effectués pour prouver ça. Parmi ces travaux, celui de Nemitari et al
[NEM17, NEM18] est le plus intéressant. Les auteurs ont analysé 79 projets logiciels orientés objet (open-
source) de différentes tailles pour étudier et comparer les dépendances logiques avec les autres dépendances
statiques et sémantiques. Les résultats de leurs études empiriques ont prouvé que :
Dans 91% des cas, les dépendances logiques impliquaient des fichiers non liés structurellement. En plus,
70% des dépendances sémantiques sont également des dépendances logiques, mais pas l'inverse.
A partir de ces résultats, nous pouvons conclu que les dépendances logiques reflètent beaucoup plus la
réalité par rapport aux autres dépendances. Une grande partie de ces dépendances structurelles et
sémantiques ne sont que des relations théoriques présentées dans la conception du logiciel seulement, mais
les artefacts reliés par ces dépendances ne se changent pas ensemble pratiquement (durant l’évolution du
logiciel). D’un autre côté, plusieurs dépendances cachées (ni statiques ni sémantiques) ne peuvent être
détectées que par une analyse de l’historique d’évolution.
Malgré la grande importance des dépendances logiques, mais elles ne sont pas encore exploitées pour
analyser la modularité de logiciel et détecter les défauts possibles. Pour cela, nous avons basé sur ces
dépendances intéressantes pour proposer notre approche d’analyse de la modularité des systèmes logiciels
OO.
2
Chapitre I : Introduction Générale
Nous pouvons résumer les contributions principales de notre travail dans les points suivants :
Chapitre II ─ Nous nous concentrerons dans ce chapitre sur la notion de la modularité d’un système
logiciel de façon général : ses caractéristiques ainsi que son principe, ses mesures. Et de la modularité des
systèmes orientés objet plus spécifiquement. Nous terminerons le chapitre par un état de l’art sur les travaux
de recherches récents traitant la modularité des logiciels.
Chapitre III ─ Dans ce chapitre, nous présenterons les systèmes de contrôle de versions, ses types, les
approches et les logiciels de versioning. Ensuite, nous définirons les dépendances logiques en les
3
Chapitre I : Introduction Générale
comparants avec les autres types de dépendances (statiques et sémantiques). Nous terminerons ce chapitre
par un état de l’art sur les approches de détection des dépendances logiques.
Chapitre IV ─ Il est consacré à notre approche proposée. Nous commencerons par une vue globale de notre
proposition. Ensuite, nous expliquerons en détail les différentes étapes de l’approche, ainsi que la conception
de notre outil réalisé.
Chapitre V ─ Dans ce chapitre, nous présenterons la mise en œuvre bien détaillée de notre approche. En
suite, des expérimentations sont effectuées pour démontrer la faisabilité et la fiabilité de notre proposition.
Chapitre VI ─ Nous clôturons notre mémoire par une conclusion générale, où nous synthétiserons les
principales contributions de notre travail. Et nous discuterons les éventuelles perspectives.
4
Chapitre I : Introduction Générale
CHAPITRE II
LA MODULARITE D’UN SYSTEME LOGICIEL
II.1 Introduction
Tout au long du cycle de vie d’un système logiciel, plusieurs actions de maintenance et d’évolution
telles que l'ajout de nouvelles fonctionnalités, la résolution de problèmes, l'amélioration de la conception, …
etc. peuvent affecter négativement la qualité de la conception du logiciel. Plus spécifiquement la dégradation
de la modularité du logiciel, ce qui peut causer de graves problèmes pour les futurs efforts d’évolution. La
modularité a été considérée comme l'une des propriétés les plus importantes d'une bonne conception de
logiciel ; de nombreuses méthodes et techniques de génie logiciel reposent sur l'hypothèse qu'une structure
modulaire de logiciel peut améliorer sa qualité dans une certaine mesure.
Par conséquent, la modularité a joué un rôle omniprésent dans le contexte de la conception de logiciels,
elle a un impact significatif sur de nombreux attributs de qualité externes tels que la réutilisabilité, la
maintenabilité et la compréhensibilité. En résumé, la modularité peut être considérée comme un principe
fondamental d'ingénierie. Dans ce chapitre nous allons présenter et expliquer la notion de la modularité d’un
système logiciel de façon général, et des systèmes orientés objet plus spécifiquement.
II.2 La Modularité
II.2.1 La conception du logiciel
La phase de conception suit immédiatement la phase d'analyse qui vise à définir une architecture
modulaire du logiciel ou encore une décomposition en modules qui facilitera la maintenance et permettra le
développement parallèle par différents programmeurs. On regroupe en général sous le terme conception
deux étapes distinctes [MOR89] :
- Conception globale : elle permet de définir les choix fondamentaux de l'architecture du logiciel en
liaison avec l'architecture matérielle.
- Conception détaillée : elle décrit précisément chaque module, les algorithmes de mis en œuvre et les
traitements effectués en cas d'erreur. La documentation produite sera très utile en phase de maintenance.
La modularité,
L’abstraction,
L’anticipation du changement,
La construction incrémentale.
Une bonne conception se définit en termes de la satisfaction des besoins et des spécifications. Les
critères de qualités peuvent donc varier énormément d'un système à un autre ou même pour deux
implantations différentes d'un même système [BOO95].
Une bonne structuration participe largement à la production d'un logiciel qui possède ces
caractéristiques. Comme dans beaucoup de domaine, cette bonne structuration se base sur la Modularité.
Le glossaire standard de l'IEEE sur la terminologie du génie logiciel [IEEE90] définit la modularité
comme le degré auquel un programme système est composé de composants discrets de sorte qu'un
changement à un composant a un impact minimal sur les autres composants.
Donc, la modularité (Figure II-1) est faite référence à un concept consistant à grouper des fonctions en
modules reliés entre eux par des interfaces et à les combiner pour former un système complet. En conception
logicielle, la modularité est opposée au raffinement.
Selon Sosa et al. [SOS06], il existe trois niveaux au concept de modularité : un niveau logiciel, un
niveau système et un niveau composant. Le degré de modularité se mesure en se basant sur le degré de
connectivité entre les composants.
Chapitre I : Introduction Générale
II.2.4 Le module
Un module est un élément de petite taille (un ou quelques sous-programmes) doit être cohérent et
autonome et qui sert, par assemblage à la construction de logiciels. La modularité se fait ressentir dans la
conception et dans la programmation [BOO95].
En génie logiciel, on considère que le développement d’un système logiciel de qualité passe par le
respect de trois critères essentiels concernant le logiciel et ses composants (modules):
La fiabilité : Un module est considéré comme fiable quand on est certain qu’il fonctionne
correctement dans tous les cas de figure.
L’extensibilité d’un logiciel : est la facilité de pouvoir l’étendre (ajout de fonctionnalités) sans
avoir à modifier l’existant.
La réutilisabilité : est la capacité des modules logiciels à pouvoir être réutilisés en partie ou en
totalité pour construire de nouvelles applications logicielles.
standardisation des processus distribués ouverts en définissant avec beaucoup de détails un ensemble de
concepts issus des pratiques de développement [JAC05].
En 2008 : La version d'UML en cours est UML 2.1.1 et les travaux d'amélioration se poursuivent
[TUR12].
De 2009 à 2014 : la modularité OO est devenue particulièrement populaire. Python, PowerShell , Ruby et
Groovy sont des langages dynamiques construits sur les principes de la POO, alors que Perl et PHP ont
été l' ajout de fonctionnalités orientées objet depuis Perl 5 et PHP 4 et ColdFusion depuis la version 6.
Ainsi que la maintenance logicielle s’est développée [BAL19].
De 2014 jusqu’à présent : La programmation modulaire est maintenant répandue et se retrouve dans
pratiquement tous les principaux langages développés depuis les années 1990.
La partie privée : contient l’implantation des opérateurs et tout ce qui s'y rattache.
II.5.1 La cohésion
II.5.1.1 Définition
La cohésion est la « connexion intérieure » entre les propriétés d'une unité de conception ou de
construction. Le principe de cohésion maximale nécessite un lien fort au sein d'une unité de conception ou
de construction [GUA15]. Si notre module effectue une seule tâche, ou a un objectif clair, notre module a
une forte cohésion. D'un autre côté, si notre module essaie d'encapsuler plus d'un objectif ou a un objectif
n’est pas clair, notre module a une faible cohésion.
La cohésion est souvent opposée au couplage. Une cohésion élevée est souvent corrélée à un faible
couplage, et vice versa.
Pressman [PRE97] représente les degrés de la cohésion, introduits par Yourdon et Constantine. Sous la
forme d'un spectre :
II.5.2 Couplage
II.4.2.1 Définition
Il a été défini comme la mesure de la force de l'association établie par une connexion d'un module avec un
autre [STE74]. Cette notion a évolué donnant comme définition : le degré d'interdépendance entre modules
[YOU79].
Nous pouvons dire alors que le couplage (Figure II-3) est la relation entre différentes unités de conception
ou de construction. Le couplage minimum tente de réduire la liaison entre les unités, en particulier pour
éviter une utilisation cyclique.
Un changement dans un module force généralement des changements dans d'autres modules.
L'assemblage des modules peut nécessiter plus d'efforts ou de temps en raison de la dépendance accrue
entre les modules.
Un module particulier peut être plus difficile à réutiliser ou à tester car des modules dépendants
doivent être inclus.
Chapitre I : Introduction Générale
Dans sa catégorisation, on distingue sept types de couplage, voici une brève description de
chacun [ZHO17] :
Couplage indirect : Il n'y a pas de couplage direct entre deux modules P1 et P2. Au niveau du
package, cela impliquerait que dans deux packages mesurées il n'y aura pas de références l'une vers
l'autre.
Couplage de données : lorsque les données d'un package sont transmises à un autre package, cela
s'appelle le couplage de données.
Couplage par timbre « Stamp » : ce type ressemble au couplage de données, mais dans le couplage
« stamp » les paramètres échangés sont des structures de données complètes i.e. au lieu de donner
toute la structure en paramètre il est préférable de donner seulement les membres ou les données dont
elle a vraiment besoin.
Couplage de contrôle : il existe entre deux packages si les données d'un package sont utilisées pour
diriger la structure d'exécution des instructions dans un autre.
Couplage externe : Un package est lié à quelque chose d'extérieur au logiciel. Au niveau de la
classe du package, cela se présente avec les bibliothèques externes.
Couplage commun : lorsque dans une classe il y a plusieurs méthodes qui partagent un même
ensemble de données. Un cas concret de ce type de couplage est l'utilisation des variables globales.
Couplage de contenu : le couplage de contenu existe entre deux packages s'ils partagent du code.
Pressman [PRE97] montre les degrés de couplage sous forme d’un spectre comme suit :
Chapitre I : Introduction Générale
Ces métriques pourraient être appliquées à des types, des champs, des méthodes, des espaces de noms,
etc. Le rapport : Ce / (Ce + Ca) est appelé Instabilité, qui mesure la résilience d'un module au changement.
Une valeur de 0 est idéale.
Cohésion Couplage
L’indication de la relation au sein du module. L’indication des relations entre les modules.
Idéalement, nous devrions viser une cohésion élevée et un couplage faible. Les parties de code associées
doivent être dans le même module. Chaque module doit être indépendant des autres et interagir de manière
minimale. En pratique, un module peut être l'un de ceux-ci, à différents niveaux d'abstraction : dossier,
fichier JavaScript, classe C ++, assemblage C #, package Java, …etc. [ZHO17].
Chapitre I : Introduction Générale
Appliquer le principe de responsabilité unique (PRU) pour une cohésion élevée. Utilisez des interfaces
bien définies et une inversion de contrôle pour un couplage faible [OFF08].
Exemple : l’exemple dans la figure II-6 montre la cohésion au sein des modules A, B et C, et le couplage
entre eux. Les sous-modules sont numérotés de 1 à 10.
Éléments mineurs : Par mineur, on entend que ces éléments sont utiles, mais ne font pas partie
indispensable du modèle objet. Les trois éléments mineurs sont :
Dactylographie : c’est l’application de la notion qu’un objet est une instance d’une seule
classe ou d’un seul type. Elle fait également respecter le fait que des objets de différents types
ne peuvent généralement pas être échangés que de façon très restreinte si cela est absolument
nécessaire.
Concurrence : il y a des objets actifs et inactifs. Les objets actifs ont des threads de contrôle
indépendants qui peuvent s’exécuter en même temps avec les threads d’autres objets. Les
objets actifs se synchronisent entre eux ainsi qu’avec des séquences purement séquentielles.
Persistance : Dans les fichiers ou les bases de données, la durée de vie de l’objet est plus
longue que la durée du processus de création de l’objet. Cette propriété par laquelle un objet
continue d’exister même après que son créateur cesse d’exister.
1. Les fonctionnalités embarquées dans une classe, accessibles via ses méthodes, ont beaucoup en
commun.
2. Les méthodes réalisent un petit nombre d'activités connexes, en évitant des ensembles de données à
gros grain ou sans rapport.
Chapitre I : Introduction Générale
La Figure II-10 illustre un exemple sur la cohésion de classe. On distingue que dans la cohésion faible,
une seule classe est chargée d'exécuter beaucoup de tâches qui ne sont pas en commun. Cela réduira les
chances de réutilisation et de maintenance. En haute cohésion, il existe une classe distincte pour exécuter
une tâche spécifique, ce qui résulte en une meilleure réutilisation et maintenance.
Un modèle de classification de cohésion est établi en prenant comme modèle la cohésion des types
abstraits de données [ALE16] :
1. Séparable : la cohésion d'une classe est classifiée séparable si l'objet représente de multiples
abstractions de données n'ayant aucune relation entre elles. C'est le cas d'une classe possédant une
méthode qui n'accède à aucune variable d’instance et n'invoque aucune des autres méthodes de la
classe.
2. Multi-facette : une classe est classifiée multi-facette si ses éléments représentent de multiples
abstractions de données liées entre elles et accessibles par au moins une méthode. Effectivement, au
moins une méthode accède à une variable d’instance ou invoque une méthode appartenant à un
concept sémantique distinct.
3. Non-déléguée : une classe est classifiée non-déléguée si elle n'est pas séparable, n'est pas multi-
facette et au moins une méthode utilise une variable d’instance décrivant seulement un composant de
la classe.
4. Cachée : une cohésion est classifiée cachée si une abstraction de données est cachée dans
l'abstraction de données représentées par la classe. Des variables d’instance et des méthodes peuvent
être vues comme une nouvelle classe à part entière.
Chapitre I : Introduction Générale
5. Modèle : la cohésion modèle est le degré le plus élevé de la cohésion de classe. Elle indique une
classe représentant un seul concept sémantique, aucune de ses méthodes ne peut être déléguée à une
classe, et elle ne renferme pas de classes cachées.
Une catégorisation du couplage applicable à la programmation OO, notamment au niveau de la classe, a été
faite [EDE95]. Dans cette catégorisation on distingue trois types de couplage :
1. Couplage d'Interaction : il survient lorsqu’une classe invoque une ou plusieurs méthodes de l'autre.
Couplage de Contenu : c'est le pire des couplages. Il signifie qu'une méthode accède directement
à l'implantation d'une méthode appartenant à une autre classe. Une telle méthode doit donc
parfaitement connaître la structure interne de la méthode qu'elle accède. En effet, tout changement
dans une méthode influence l'autre.
Couplage Commun : il signifie que plusieurs méthodes partagent un même ensemble de
données. Le couplage commun est meilleur que le couplage de contenu, dans le sens que toutes les
communications implicites sont regroupées dans un endroit commun. Néanmoins, le nombre de
communications entre les différentes méthodes est polynomial, et le principe de localité d'une bonne
conception orientée objet n'est pas considéré.
Couplage Externe : Dans ce type de couplage, les données partagées sont structurées de telle
manière à faciliter leurs accès par les différentes méthodes. Cependant, le principe de localité
[Pres97] n'est toujours pas respecté, et la plupart des inconvénients du couplage externe sont toujours
présents.
2. Couplage d'Héritage : deux classes présentent un couplage d'héritage si une des deux classes est
directement ou indirectement une sous-classe de l'autre.
Chapitre I : Introduction Générale
3. Couplage de Contrôle : une classe présentant un couplage de contrôle communique avec une méthode
d'une autre classe à travers le passage de paramètres.
Couplage "Stamp" : deux classes présentent un tel couplage, si deux de leurs méthodes
respectives se passent comme paramètre une structure de données entière alors qu'une partie de
cette structure aurait suffi.
Couplage de Données : deux classes présentent un couplage de données, si elles échangent des
données seulement en paramètres. Ce type de couplage est le plus recommandé dans les systèmes
orientés objet. Le couplage de données minimise l'effort de maintenance grâce aux restrictions de
la propagation des changements.
Couplage Non-direct : deux méthodes ne dépendent pas directement l'une de l'autre. Chaque
changement dans une des méthodes n'influence aucune autre méthode.
Couplage de Composant : une classe, utilisant comme variable d’instance une autre classe,
présente un couplage de composant avec cette dernière.
Dans la programmation OO, la classe n'est jamais était un élément suffisant pour une bonne description de la
modularité d'un projet logiciel au complet. A ce niveau-là, il est indispensable de disposer d'un constituant
de granularité plus élevée et important pour une excellente représentation d’un système à une échelle
appropriée. Ces composants sont les Packages [STE17].
Dans [WAR04] un ensemble de principes qui s'appliquent au niveau des packages sont présentés. Voici
une brève description de quelques-uns :
Le principe des dépendances acycliques (ADP Acyclic Dependencies Principle) : Ici, les
dépendances entre les packages doivent, former un graphe acyclique. Ce principe est trop utilisé dans
un grand projet et les packages ont été utilisés comme éléments pour distribuer le travail.
Le principe des dépendances stables (SDP, Stable Dependencies Principle) : Selon ce principe,
une mauvaise dépendance est celle qui dépend d'éléments très volatils. Au contraire, une bonne
dépendance est celle qui dépend d'éléments très stables. Par conséquent, c’est plus difficile de
changer un module.
II.7 Etat de l'Art sur les travaux traitants la modularité des systèmes
orientés objet
Morris [MOR89] : a mesuré la cohésion du module en quantifiant le fan-in des objets que le module
contient.
Eder et coll [EDE92]: ont défini trois types de cohésion dans les systèmes logiciels OO, c'est-à-dire la
cohésion de méthode, la cohésion de classe et la cohésion d'héritage.
Chapitre I : Introduction Générale
Patel et coll [PAT92]: ont proposé une métrique pour mesurer la cohésion des sous-programmes en
quantifiant la similitude entre différentes paires de sous-programmes.
Chidamber et Kemerer [CHI94]: ont proposé le manque de cohésion dans les méthodes (LCOM) pour
mesurer la cohésion de classe.
Chidamber et Kemerer [CHI94]: ont proposé une suite de métrique CK (Chidamber&Kemerer) pour
mesurer les couplages logiciels.
Bieman et Kang [BIE95]: ont défini deux métriques de cohésion de classe, Tight Class Cohesion
(TCC) et Loose Class Cohesion (LCC), pour mesurer la cohésion de classe en comptant le nombre de
paires de méthodes dans une classe qui accèdent aux attributs communs.
Lee et Liang [LEE95]: ont défini une métrique Information CoHesion (ICH) basée sur le flux
d'informations.
Briand et coll [BRI99]: ont appliqué un graphe d'interaction pour représenter la structure du logiciel et
proposé une suite de métriques de cohésion.
Brito et Goulão [BRI01]: ont analysé la modularité de la conception des systèmes OO. À ce niveau
d'abstraction, le module est un ensemble de classes. Ils ont utilisé les informations sur les dépendances
entre les classes pour évaluer la modularité.
Bansiya et Davis [BAN02]: ont défini une métrique, Cohesion Among Methods of Classes (CAMC),
pour mesurer la cohésion de classe en quantifiant la similitude des méthodes en fonction de leurs listes
de paramètres.
Martin [MAR02]: a défini une métrique, la cohésion relationnelle (RC), pour mesurer la cohésion d'un
package en utilisant le rapport du nombre de relations de données et du nombre de composants dans un
package.
Jenkins et coll [JEN07]: ont défini une métrique, Icc, pour mesurer la stabilité du logiciel en fonction
des classes et de leurs couplages.
Ardourel et Huchard [ARD08]: ont étudié l'encapsulation et la modularité dans les langages orientés
objet avec Access Graphs.
Jeff et al. [OFF08]: ils ont utilisé les interdépendances complexes des langages OO pour définir les
types de couplage. Ils se concentrent sur les couplages interclasses plutôt que sur les couplages intra-
classes. Les couplages intra-classes sont les mêmes pour les logiciels orientés objet et procéduraux
Varun et Chhabra [GUP10]: une nouvelle métrique est proposée pour mesurer la cohésion au niveau
des package afin d'obtenir des packages de bonne qualité.
Przybylek [PRZ10]: a réalisé une évaluation empirique de l'impact de la programmation orientée aspect
sur la modularité logicielle.
Chapitre I : Introduction Générale
Christian et al. [KAS11]: ont distingués deux notions de modularité, de cohésion sans interfaces et
avec interfaces.
Abdeen et Ducasse [ABD11]: ont fourni un ensemble complémentaire de mesures qui évaluent certains
principes de modularité pour les packages de grands logiciels OO hérités: principes de masquage des
informations, de capacité de modification et de réutilisation.
Cherait [CHE14] : a exposé une approche basée sur l'histoire qui détecte les défauts de modularité dans
les logiciels orientés aspect évolués. Les modifications sont formulées sous forme de règles de
réécriture et enregistrées dans le dépôt lorsqu'elles sont appliquées. Ce dernier est analysé pour détecter
les patterns de changement dans l'évolution du logiciel AspectJ.
Eder et al. [EDR14]: ont introduit une taxonomie complète des propriétés de couplage et de cohésion
des systèmes orientés objet et fournir des lignes directrices pour améliorer ces propriétés.
Guan et al. [GUA15]: ont exploré la structure communautaire dans les systèmes logiciels et mesuré la
cohésion de classe à l'aide de techniques de détection communautaire.
Clyde et Lascano [CLY17]: ont proposé des définitions unifiées initiales pour la modularité,
l'abstraction et l'encapsulation qui sont applicables à plusieurs paradigmes de programmation OO. Il
montre ensuite que ces définitions unifiées ne sont pas redondantes mais complémentaires les unes des
autres.
Laval [LAV17] : a proposé une analyse des dépendances des packages dans les systèmes OO qui aide à
la re-modularisation. Elle concerne les trois domaines de recherche suivants : Comprendre les
problèmes de dépendance entre packages, mettre en évidence les dépendances cycliques au niveau des
packages et de proposer des dépendances qui devraient être changées.
Gu et al. [GU17]: une nouvelle métrique de cohésion basée sur des réseaux complexes (CBCN) pour
mesurer la connectivité des membres de la classe a été développée principalement en calculant le
coefficient de regroupement moyen de la classe à partir de graphiques représentant les modèles de
connectivité des différents membres de la classe.
Gu et al.[GU17a]: ont proposé une nouvelle métrique pour mesurer la cohésion de classe basée sur le
calcul du coefficient de regroupement moyen du réseau logiciel au niveau de la classe.
Zhang et al. [ZHA18]:ont appliqué des techniques de détection communautaire pour mesurer la
cohésion d'un système logiciel.
Xiang et al. [XIA19]: ont introduit la théorie des réseaux complexes dans l'ingénierie logicielle et ont
utilisé une métrique largement utilisée dans le domaine de la détection communautaire dans la recherche
de réseaux complexes, pour mesurer la modularité du logiciel dans son ensemble
Chapitre I : Introduction Générale
II.8 Conclusion
Nous avons présenté dans ce chapitre, la notion de modularité en général et au niveau des systèmes OO
spécifiquement. Une forte cohésion au sein des modules et un faible couplage entre eux sont la clé vers à
une bonne modularité des systèmes logiciels. A la fin de ce chapitre, nous avons donné un bref état de l’art
sur les travaux traitants la modularité des systèmes OO.
En étudiant les travaux dans ce domaine de recherche, nous avons constaté que chaque travail utilise un
type de dépendances donnés (statiques, sémantiques, …) pour analyser la modularité du système. Mais
aucun travail n’a utilisé un type de dépendances très intéressant et qui représente un domaine de recherche
actif actuellement, ce qu’on appelle « les dépendances logiques ». Ces dépendances sont très intéressantes
puisque qu’elles sont extraites à partir de l’historique d’évolution du logiciel. Par conséquent, elles peuvent
donner une vue plus exacte sur la modularité du logiciel et son évolution à travers le temps. Cela nous a
inspiré pour proposer notre approche. Nous présenterons ce qu’on signifie par une dépendance logique et les
techniques utilisés pour les extraire dans le chapitre suivant.
Chapitre I : Introduction Générale
CHAPITRE III
LA DETECTION DES DEPENDANCES LOGIQUES :
FOUILLE DE DONNEES
III.1 Introduction
Dans le cycle de vie d’un logiciel, l’évolution est la phase la plus importante. Le développeur fait
évoluer son logiciel pour améliorer ses fonctionnalités existantes, ou pour ajouter des nouvelles
fonctionnalités afin de l’adapter à son environnement. L’historique de l’évolution de logiciel géré par
les systèmes de contrôle de versions présente une source très riche d’information autour de ce
logiciel. L’analyse de cet historique d’évolution est une zone de recherche très active actuellement, à
travers laquelle le développeur peut extraire des méta-informations intéressantes pour l’aider à
comprendre l’évolution du logiciel et prédire ses futurs changements.
Supporter principalement une meilleure collaboration asynchrone entre les développeurs i.e. les
SCVs permettent la gestion de différentes versions dans une équipe de développeurs coopérants, tel
que chaque membre peut extraire, modifier certains fichiers, puis les archiver à nouveau.
Meilleure sécurité en garantit l’intégrité, disponibilité et confidentialité. Car seuls les développeurs
autorisés peuvent avoir accès aux informations. Chacun doit prouver son identité par l'usage de
code d'accès. Les versions de logiciels doivent être exactes et complètes.
Les systèmes de contrôle de versions locaux (Local VCS): La plupart des développeurs, pour
contrôler les versions de leur travail, copient les fichiers dans un autre répertoire, peut être un
répertoire associe à la date et l'heure de la modification effectuée. C'est la manière la plus simple de
le faire, mais c'est aussi la moins fiable puisqu'elle peut être une vraie source d'erreurs.
Chapitre I : Introduction Générale
Il est facile d'oublier le répertoire dans lequel nous sommes et de modifier accidentellement dans le
mauvais fichier, ou bien écraser une nouvelle version de notre travail par une ancienne. Pour
remédier à ce genre de problème, les programmeurs ont développé des SCVs locaux (Figure III.3), ce
sont des petits systèmes avec une simple base de données qui garde tous les changements des fichiers
sous contrôle [CHE14]. On peut citer par exemple : CVS, Subversion et Perforce. Néanmoins, ce
genre de système souffre d’un inconvénient, c’est que, si la machine ou le disque dur qui contient la
base de données tombe en panne, tout le travail est perdu.
Les systèmes de contrôle de versions centralisés (Centralized VCS) : ils stockent toutes les
versions des fichiers dans un seul serveur central. Les développeurs interagissent avec ce dernier
pour récupérer (faire des checkout) leurs fichiers et contrôler leurs versions.
Les systèmes de contrôle de versions distribués (Distibuted VCS) : Dans ce type de SCVs,
comme Git, Mercurial et autres, les développeurs n'extraient plus seulement (checkout) le dernier
snapshot des fichiers, mais ils dupliquent complètement le dépôt (Figure III.5). Ainsi, si un serveur
tombe en panne, l'un des dépôts des développeurs pourra être copié sur le serveur pour le restaurer.
Chaque checkout est vraiment une sauvegarde complète de toutes les données (les changements)
[CHE14].
Les approche basées opération : Ils ne fonctionnent pas sur les états d'un artefact, mais
sur les séquences d'opérations qui ont été appliquées simultanément à la version
originale [BRO12].
GNU arch (2001) · Darcs (2002) · DCVS
(2002) · SVK (2003) · Monotone (2003) · Codeville
Décentralisé
(2005) · Git (2005) · Mercurial (2005) · Bazaar (2005) · Fossil (
2007) · Veracity (2011) · Pijul (2015)
Commit : Envoi de modification sur le dépôt. Il peut y avoir des conflits avec la version du dépôt
lors de la fusion des modifications (merge). Les conflits doivent être résolus pour que les
modifications soient enregistrées.
Les conflits : C’est le résultat de deux modifications simultanées faites sur le même artefact logiciel.
Les types les plus fondamentaux de conflits sont [MES13] :
Update-Update conflits : se produisent si deux éléments ont été mis à jour dans les deux
versions.
Delete-Update conflits : se produisent si un élément a été mis à jour dans une version et
supprimé dans l’autre.
Révision : identificateur unique d'un état des données (ce n'est pas la version d'un projet).
Étiquettes (Tag) : marque symbolique sur une révision (permet de définir les versions de projet, de
nommer les branches ...).
D’après Kerstin Altmanninger et al. [ALT09], les fonctionnalités (Figure III-6) d’un SCV sont :
Collaboration : Cette fonctionnalité a pour but d’empêcher d'écraser accidentellement les
modifications mutuelles des artéfacts partagés entre les développeurs. Deux mécanismes sont
utilisés :
Optimiste : Cette méthode est beaucoup plus souple car elle considère que les conflits sont
l'exception et les laisse à la charge du développeur en le laissant modifier sa propre version
du fichier, et à régler les conflits lors d'une synchronisation, cas par cas.
Pessimiste : les conflits sont la règle. Elle manque de souplesse car elle empêche la
concurrence (un développeur ayant verrouillé un fichier empêche les autres d’avancer). Son
Chapitre I : Introduction Générale
rôle est d’interdire tout changement dès qu’un des développeurs commence à modifier une
version jusqu’à ce qu’il valide ses changements.
Le fusionnement (Merging) : Lorsqu’un artefact logiciel subi une modification, ce mécanisme est
utilisé pour fusionner les deux versions. Il est appliqué seulement lorsque la condition de conflit n’est
pas satisfaite ; Il existe trois types de merging :
Raw : applique simplement une séquence d'opérations de changement. Cette dernière est une
combinaison des modifications apportées par les développeurs [ALT09].
Two-way : On compare deux versions différentes V 'et V" et les fusionne en une seule
version V sans avoir accès à la version de la quelle V' et V" origines.
Three-way : c’est le fusionnement le plus fiable, car il faut que le V « ancêtre commun de
deux versions V' et V" » soit prise en compte et donc être en mesure d'examiner les éléments
supprimés [ALT09].
Repository architecture : L'architecture du dépôt décrit comment les développeurs communiquent
leurs modifications aux artefacts les uns aux autres. Il existe deux aspects [MAI10] :
Centralisé : chaque modification effectuée exige un accès en écriture sur un dépôt central
unique. De ce fait, il est impossible de maintenir une branche parallèle d’un projet dont on
n’est pas contributeur.
Distribué (décentralisé) : Chaque utilisateur a la possibilité de créer son convenable dépôt
depuis un autre, d’accomplir des changements locaux. Ensuite, il peut récupérer les
changements ultérieurs depuis la source, voire de propager ses propres modifications si l’on
dispose d’un accès en écriture.
logiciel peut vivre. Il peut être un endroit local directement accessible aux développeurs, ou comme une ou
plusieurs bases de données où les fichiers sont localisés en vue de leur distribution sur le réseau.
Un dépôt offre aux programmeurs un moyen structuré de stocker les fichiers de développement. Pour
chaque fichier dans le logiciel, il enregistre des indications importantes comme [HAS08] :
En validant des modifications dans un dépôt, les développeurs peuvent rapidement revenir à une version
précédente d'un logiciel si une mise à jour récente provoque des bogues. Ils peuvent annuler les nouveaux
changements trouvés sans rapport, ou même récupérer une version anicienne du code. De ce fait, cette action
rend la version perceptible à d’autres développeurs [HAS08].
L’extraction des données : Cette étape consiste à avoir l’accès aux données entreposées dans les
dépôts de SCVs.
Chapitre I : Introduction Générale
logiciel peut aider à extraire ces dépendances intéressantes entre ses entités appelées « dépendances
logiques » ou « couplages logiques ». Ce genre de relations évolutives est difficile à détecter
explicitement à partir de l’analyse d’une seule version du code source.
induire ce type de relations. Ces dépendances de code structurel statique sont le plus souvent utilisées
lors de l'analyse ou de l'exploitation du couplage [AJI18].
Nous avons cité dans les sections précédentes que le couplage logique décrit les dépendances de
changement entre les entités d'un système logiciel depuis son historique d'évolution, alors que le
couplage structurel mesure les dépendances du code source induites via l'architecture du système
logiciel [LIG07].
Ajienka et al. [NEM17] ont effectué une étude empirique très intéressante sur un échantillon de
79 projets logiciels open-source afin de déterminer s'il existe une relation entre le couplage
‘structurel et logique’ entre les classes d’un logiciel orienté objet (OO). Les résultats ont prouvé
que :
Il existe un léger chevauchement entre les dépendances structurelles et logiques dans la majorité
des projets logiciels. Cependant, il y a une probabilité plus élevée de dépendances structurelles
conduisant à la coévolution des classes, mais une faible chance de pouvoir déduire un couplage
structurel à partir de la coévolution.
Il n’existe en réalité aucune preuve solide permettant de penser qu’il existe une relation linéaire
entre les points forts de différents types de couplages. Donc, un couplage structurel fort n'implique
pas une probabilité de Co-changement plus élevée.
Plus de 30% de toutes les transactions de changement n'ont rien à voir avec le couplage structurel.
Plus de 50% des transactions de changement avaient eu au moins un changement non structurel.
Dans 91% des cas, les dépendances logiques impliquaient des fichiers non liés structurellement,
la plupart des dépendances logiques n'étaient pas directement causées par des dépendances
structurelles.
Presque 80% des dépendances de classes structurelles incluent des dépendances logiques mais pas
l'inverse.
Par conséquent, nous avons conclu que les dépendances logiques sont plus intéressantes pour l’analyse
de la modularité de logiciel que les dépendances structurelles.
de programme, il est donc important de les définir clairement, car les identificateurs auto-
documentés diminuent le temps et les efforts nécessaires pour acquérir un niveau de compréhension
de base pour une tâche de programmation [AJI17].
Ajienka et al. [NEM18] ont effectué aussi une recherche empirique pour savoir s’il existe une
relation logique sémantique ou non. Ils ont analysé 79 projets logiciels OO Open source. Ils n’ont
pas détecté de relation linéaire entre les dépendances sémantiques et logiques. Cependant, ils ont
identifié un lien bidirectionnel entre les deux. En d'autres termes, plus de 70% des classes liées
sémantiquement vont généralement évoluer. En même temps, les classes liées au changement
partagent généralement un certain degré de couplage sémantique.
Par conséquent, on peut déduire encore une fois que les relations logiques sont la source la plus riche pour
analyser la modularité de logiciel OO par rapport aux autres dépendances (structurelles, et sémantiques).
Afin d’atteindre l’ensemble des dépendances logiques ciblées, il faut d’abord passer par des phases très
intéressantes (Figure III-8) comme suit :
consécutives du logiciel. Un changement sur le logiciel est les différentes opérations appliquées par le
développeur : ajout, suppression, modification d’une entité ou d’une opération.
Le résultat de la phase d’extraction des transactions sera analysé par différents algorithmes qui peuvent
être employés dans le but de détecter l’ensemble des éléments fréquents (i.e. les dépendances logiques). Ce
sont les entités qui se changent souvent ensemble. Selon Boulanger et Alain [BOU09], les itemsets fréquents
sont générées en fixant un support minimal. Ils ont défini formellement le support et la dépendance logiques
comme suit :
Support d’une dépendance logique (frequent itemset)
Supposons IR un ensemble d'items, 𝑟 une BDD sur IR et Y⊆ IR un itemset. On note M(𝑟,Y) = {𝑡∈𝑟
| Y⊆𝑡}, le multiset de transactions qui contiennent Y. Le support de Y sur M est noté
𝑠𝑢𝑝𝑝𝑜𝑟𝑡(M,Y) =|M(𝑟,Y)| et signifie le nombre de transactions dans M correspondant à Y . Le
support peut être représenté de manière absolue, relative ou en pourcentage.
A. L’algorithme Apriori : est un algorithme classique de recherche de règles d’association. Comme tous
les algorithmes d’extraction des règles d’associations, il travaille sur des bases de données transactionnelles.
C’est l’algorithme que nous allons utiliser dans notre approche.
E. L’algorithme kDCI (k Direct Count & Intersect) : est un algorithme hybride multi-stratégies basé
sur l’algorithme DCI. L’algorithme recueille des informations sur la base de données durant l’exécution afin
de déterminer la meilleure stratégie à adopter selon quelles données sont denses ou éparses.
Chapitre I : Introduction Générale
F. L’algorithme FIN : Au cours des dernières années, deux nouvelles structures de données ont été
proposées Nlist et Nodelist pour représenter les itemsets. Les deux structures sont basées sur une structure
arborescente appelée PPC-Tree, qui stockent les informations pour chaque motif fréquent.
III.4.5 Etat de l'Art sur des approches de détection des dépendances logiques
Parmi les approches et les techniques les plus récents et les plus intéressants dans un ordre chronologique
croissant (de l’ancien vers le plus à jour) nous pouvons trouver :
Piatetsky et Shapiro [PIA91] : En se basant sur le concept de relations fortes. Ils présentent des
règles d'association exceptionnellement fortes, découvertes dans des bases de données en usant des
distinctes mesures d'intérêt.
Gall et al. [GAL98] : ont détecté les points possibles de maintenabilité en analysant les relations du
Co-changement des modules qui pointent aux relations cachées, et aux points faibles de la structure
d'un système logiciel, en fonction de l'historique de version du code source.
Bieman [BIE03] : a présenté une étude fondée sur des métriques pour détecter les classes sujettes au
changement, i.e. les classes qui se changent continuellement et les groupes de classes qui se changent
fréquemment ensemble.
Hassan et al. [HAS04] : ont utilisé une variété des heuristiques, comme la relation basée sur les
développeurs, l'historique, la disposition de code (basée sur le fichier) pour découvrir les entités
candidates à un changement en raison du changement d'une entité données.
Ying et al. [YIN04] : Au niveau du fichier, ils ont proposé une approche de prédiction de
changement de code source. Une technique d'extraction par association basée sur l'extraction
d'ensembles d'éléments d'arbres FP est utilisée. Pour indiquer leur intérêt, les règles minées sont
classées dans des catégories surprenantes, neutres ou évidentes. La technique est évaluée sur
l'historique des versions des projets Mozilla et Eclipse.
Ying et al. [YIN05] : En se basant sur les règles d'association, ils ont proposé une technique pour
déterminer l'impact du changement.
Ratzinger et al. [RAT05] : ont exploité des données historiques extraites à partir des dépôts et se
concentrent sur les couplages du changement (change couplings).
Zimmermann et al. [ZIM05] : ont appliqué le Data Mining aux historiques de version pour extraire
les patrons du changement. Ces derniers sont utilisés pour guider les programmeurs dans le
développement et la maintenance du logiciel.
Kagdi et al. [KAG06] : ont appliqué l'exploration de modèles séquentiels pour découvrir les fichiers
fréquemment modifiés avec les informations supplémentaires de leur ordre de modification.
Chapitre I : Introduction Générale
Askari et Holt [ASK06] : ont désigné une approche théorique de l'information pour évaluer les
modèles probabilistes. Ceci a été utilisé pour deviner les changements et les bugs dans les fichiers
logiciels. Le modèle est évalué en comparant la distribution des valeurs prédites (par exemple, les
changements de fichiers) avec la vraie distribution (i.e. les observations réelles).
Gino Chénard [CHE07] : a réalisé une approche automatique pour l'extraction des règles
d'association d'un logiciel.
Wong et al. [WON10] : les auteurs formalisent le couplage logique comme un processus
stochastique en utilisant un modèle de chaine de Markov.
Abdou Maïga [MAI10] : a fait la détection et correction automatique des défauts de conception au
moyen de l’apprentissage automatique pour l’amélioration de la qualité des systèmes.
Ben nedjema et Benlaiter [BEN12] : ont proposés une approche qui fait l’extraction des règles
d’association pour l’aide à la décision.
Cherait et Bounour [CHE15] : ont proposé des approches pour extraire les patrons du changement
et les dépendances logiques au niveau des logiciels orientés aspect (OA). Ces dernières sont utilisées
pour détecter les défauts de modularité au niveau de ces logiciels OA.
Guendouzi Wassila [GUE17] : a réaliser une approche bio-inespérée pour la détection d’intrusions
dans un réseau d’ordinateurs.
Mokhtari et Moulkhaloua [MOK18] : ont proposé un système DE Détection D'intrusions
Informatiques par Système Multi-Agents.
III.5 Conclusion
Nous avons présenté dans ce chapitre les systèmes de contrôle de version qui aident les
développeurs à entreposer et gérer leurs versions du logiciel au fil du temps. Nous avons aussi
exploré le domaine e l’analyse d’historique d’évolution, plus spécifiquement la détection des
dépendances logiques : son principe, ses étapes primordiales, et les algorithmes de Mining. Nous
avons clôturé par un état de l'art sur des approches de détection des dépendances logiques.
Dans le chapitre suivant nous allons présenter en détails notre approche proposée. Nous visons à
utiliser les dépendances logiques extraites entre les classes (et par conséquent entre les packages) à
partir d’un dépôt de version d’un logiciel OO pour étudier sa modularité.
CHAPITRE IV
NOTRE APPROCHE D’ANALYSE
DE LA MODULARITE DES LOGICIELS OO
IV.1 Introduction
Nous présentons dans ce chapitre, notre approche d’analyse de la modularité des logiciels OO. Cette
analyse permet de détecter les défauts de modularité possibles. Le principe consiste à analyser l’historique
d’évolution du logiciel OO pour générer les dépendances logiques entre ses classes. Ensuite, ces
dépendances sont analysées afin de visualiser : 1) les relations de cohésion dans les packages, et 2) les
relations de couplage entre les packages. Le couplage et la cohésion seront les mesures de la modularité
utilisées dans notre approche. Les résultats obtenus seront délivrés au développeur du logiciel, qui peut
appliquer des techniques adéquates dans le but d’améliorer sa modularité.
Nous commençons par une vue globale de notre proposition. Ensuite, nous présenterons soigneusement
et de manière approfondie les différentes étapes de notre approche.
1. L’analyse du dépôt de versions du logiciel OO pour générer les dépendances logiques entre
ses classes sous forme de règles d’association.
2. L’analyse des dépendances logiques générées dans l’étape précédente pour détecter les
relations de cohésion et de couplage :
a. Relations de cohésion ou dépendance interne : les dépendances logiques entre des
classes qui appartiennent au même package.
b. Relations de couplage ou dépendance externe : les dépendances logiques entre des
classes qui n’appartiennent pas au même package.
Les résultats obtenus par notre approche peuvent nous donner une idée claire sur la modularité du logiciel
OO. Les relations de cohésion et de couplage nous aident à détecter les défauts de modularité.
Une bonne modularité = forte cohésion dans les packages + faible couplage entre
packages
Ces résultats seront exploités par le développeur du logiciel dans le but d’améliorer sa modularité.
Figure IV-012:Vue globale de notre approche.
Nous devons analyser le dépôt d’un système de contrôle de version d’un projet OO pour extraire les
dépendances logiques entre ses classes sous forme de règles d’association. Cette étape est constituée des
quatre sous-étapes suivantes :
1 . Extraction de données
2 . Différenciation entre les versions du logiciel OO
3 . Prétraitement des données
4 . La fouille de données (Mining)
Figure IV-13: Les étapes de la génération des dépendances logiques.
IV.3.2 La Différenciation
Dans l’objectif de faire évoluer et maintenir le logiciel, le développeur applique des changements qui
peuvent êtres : un ajout, une modification ou une suppression d’un artefact logiciel ou d’une association.
Afin d’extraire les transactions de changement dans le dépôt de version, nous appliquons la différenciation
entre chaque deux versions consécutives d’un logiciel OO. Comme résultat est à partir de N versions du
logiciel, nous obtenons N-1 transactions de changement.
Les algorithmes de Mining cités dans le chapitre précèdent (section III.3.5.4) exigence un format
spécifique pour les transactions de changement. Donc, nous devons se focaliser sur le format de l’algorithme
que nous allons utiliser. Dans notre cas c’est l’algorithme « Apriori ».
IV.3.4 La fouille de données (Mining)
Les résultats obtenus dans l’étape précédente (transactions de changement filtrées), doivent êtes
analysées pour détecter les dépendances logiques entre les classes du logiciel OO. Le principe est exprimé
dans l’exemple suivant :
Exemple : soit les trois transactions de changement T1, T2 et T3 définies comme suit :
- T1=C1, C2, C3, C6.
- T2=C1, C3, C5, C7.
- T3 =C1, C8, C3, C4.
A partir de ces transactions, nous pouvons remarquer que les classes C 1 et C3 sont changées ensemble
dans les trois transactions. Cela signifie que lorsque les développeurs ont changé la classe C 1, ils ont
également changé la classe C3. Puisque ces classes sont changées souvent ensemble, nous pouvons déduire
qu’il existe une relation de dépendance logique entre eux.
Dans notre approche, nous avons choisi d'utiliser l'algorithme Apriori pour faire le Mining. Cet
algorithme expose nettement les classes fréquemment changées ensemble avec leurs packages sous forme de
règles d'association.
A. L'algorithme Apriori
L'algorithme Apriori [AGR94] est un algorithme d'exploration de données conçu en 1994, par Agrawal
et Sikrant, dans le domaine classique de recherche de règles d'association. Malgré qu’il est un ancien
algorithme ; mais il est toujours considéré comme l’un des algorithmes les plus performant dans le domaine
de Mining, et c’est pour ça il est très utilisé dans les travaux récents. Apriori sert à reconnaitre des propriétés
qui reviennent fréquemment dans un ensemble de données, Pour révéler la pertinence d'une règle on utilise
deux concepts qui sont « le support » et « la confiance » (confidence) (voir la section III.3.5.1).
Afin d'être retenue, chaque règle devra avoir un support supérieur à minSupp et une confiance
supérieure à minConf. Ces deux valeurs étant définies empiriquement par l'utilisateur de l'algorithme.
L'algorithme Apriori (Listing IV.1) est conçu pour opérer sur les bases de données qui contiennent des
transactions. Donné un ensemble d'items « Itemsets », l'algorithme essaie de trouver des sous-ensembles qui
sont communs à au moins un nombre minimum C d'itemsets.
L1 = { large1 - itemsets };
for (k=2; lk-1 ≠; k++) do begin
ck = apriori - genL k-1; // New Candidates
for all transactions t ϵ D do begin
Ct = subset(Ck ,t) // candidates contained in t
for all candidates c ϵ Ct do c.count ++;
end
Lk = {c ϵ Ck│c.count_ minsup }
end
Answer =*$Uk Lk$*
Listing IV-1:L'algorithme Apriori [BOU09]
Pour générer les dépendances logiques entre les classes de l'application OO avec l'algorithme Apriori,
nous avons suivi le principe suivant : soit C={c1, c2,…,cn} un ensemble des classes du logiciel OO, et X ⊆ C
un sous ensemble de classes. Nous définissons le dépôt D comme un ensemble de transactions de
changement D={t1, t2,…tm}, où ti = {ci1, ci2,…,cik} et cijϵ C. Donc, soit s(X) l'ensemble de transactions qui
contient l'ensemble des classes X, formellement s(X)={YD│Y⊆X}. Finalement, le support de l'ensemble
de classes X est la fraction de transactions dans le dépôt qui contient X :
¿
Support(X)=¿ s(X )∨ ¿ D∨¿¿ ¿
Donc, X est appelé une dépendance logique quand son support est plus grand qu'un support minimum
donné : support(X) ≥ minsupport.
Dans d'autre terme, la force d'une dépendance logique {c1, c2,…,cn} où chaque ci est une classe, est
mesurée par le support qui est le nombre (ou pourcentage) de transactions qui contiennent les classes c 1, c2,
… ,cn.
Une règle d'association est une relation unidirectionnelle de la forme C 1⇒C2 entre deux ou plusieurs
classes. La partie gauche de la règle C 1 est appelée les antécédents, ce sont les classes qui peuvent être
changés, et la partie droite C2 est appelée les conséquents, qui représentent les classes touchées par le
changement des antécédents de la règle.
Après la génération des dépendances logiques sous forme de règles d’association, elles seront
entreposées dans une base de données. Cette dernière sera utilisée par notre outil d’analyse de modularité
pour détecter les différentes relations de cohésion et de coulage dans le logiciel OO.
IV.4 L’analyse de la modularité des logiciels OO
Cette phase utilise les règles d’association générées dans l’étape précédente afin d’aider le développeur à
analyser la modularité du logiciel OO d’une façon correcte. Cette analyse est basée sur la décomposition
structurelle du logiciel OO en tant que packages. Nous pouvons distinguer deux types de dépendances
logiques (Figure IV.5) :
Dépendance logique interne : met en relation deux classes appartenant au même package dans la
décomposition logicielle.
Dépendance logique externe : relie deux classes appartenant à deux packages logiciels différents
(indépendants).
Pour évaluer l’interdépendance des packages du logiciel OO, nous nous sommes basés sur les dépendances
précitées pour proposer deux concepts intéressants : la cohésion logique, et le couplage logique.
Si nous constatons l’exemple illustré dans la figure IV.7, nous pouvons déduire que :
Une dépendance logique externe dans le logiciel OO peut être définie formellement comme suit :
Définition d'un couplage logique externe: soit A et B deux packages. S’il existe une dépendance
logique entre les deux classes x, y (x,y) tel que x ϵ A et y ϵ B, donc elle est une dépendance logique
externe entre les deux packages A et B.
Le couplage logique d’un package est mesuré par le nombre de dépendances logiques externes reliant ce
package avec le reste des packages du logiciel OO. Formellement, un ensemble de dépendances
logiques externes DLE pour un package A est défini comme suit:
Puisque chaque dépendance logique a une force (support). Ainsi, nous pouvons dire que deux packages
sont fortement liés si le support de la dépendance entre eux est grand et vice versa. Par conséquent, et à
travers notre analyse nous pouvons détecter les packages fortement liés et ceux faiblement liés.
Défauts de modularité = faible cohésion dans un package OU fort couplage entre des
packages
Une faible cohésion : les classes qui appartiennent au même package ne se changent pas ensemble,
ce qui conduit à une faible cohésion du package. Cela est considéré comme un défaut de modularité
puisqu’une bonne modularité nécessite une forte cohésion dans les packages du logiciel.
Un fort couplage : l'existence des couplages logiques dans un système logiciel présente des défauts
de modularité possibles dans ce système. Deux packages qui sont censés être modifiés
indépendamment sont modifiés ensemble, i.e. un changement dans une classe qui appartient à un
package spécifique nécessitera des changements dans une ou plusieurs autres classes qui
appartiennent à d'autres packages. Plus le couplage est fort, plus il y a de possibilité qu’il s’agisse
d’un vrai défaut de modularité.
En résumé, un fort couplage ou une faible cohésion dans un logiciel OO montrent que la modularité dans
ce système est violée. Les packages concernés seront des candidats à la restructuration ou à la
refactorisation. Ici, les défauts de modularité détectés sont utilisés pour orienter les développeurs à effectuer
des améliorations ; afin d'obtenir une meilleure stabilité avec très peu de dépendances, i.e. une situation
idéale permettrait de changer chaque package indépendamment des autres. Ceci est très utile pour
reconstruire une meilleure modularisation pour le système logiciel OO et une bonne réutilisabilité de leurs
packages.
Dans ce qui suit des diagrammes UML sont utilisés pour refléter notre conception.
IV.5.1 Diagramme de cas d’utilisation
Les fonctionnalités fondamentales de l'application à élaborer sont présentées dans le diagramme de cas
d'utilisation présenté dans la figure IV-9 :
1. Générer les règles : dans le but de générer les règles d'association d'une application Java à partir de
son dépôt de versions.
2. Visualiser les règles : le développeur (l’utilisateur de l’outil) peut consulter toutes les règles
d'association d'une application Java.
3. Générer et visualiser la cohésion d’un package : analyse les règles d’association pour un package
donné pour déduire et visualiser ses relations de cohésion logique.
4. Générer et visualiser le couplage d’un package : analyse les règles d’association pour un package
donné pour déduire et visualiser ses relations de couplage logique.
Figure 0-9: Diagramme de cas d'utilisation de notre application.
IV.6 Conclusion
Nous avons présenté dans ce chapitre les étapes détaillées de notre approche d’analyse de la
modularité logique pour les logiciels OO. Notre proposition est subdivisée en deux phases
primordiales : l’analyse du dépôt de versions du logiciel OO pour générer les dépendances logiques
entre ses classes sous forme de règles d’association. Ensuite, l’analyse des dépendances logiques
générées dans l’étape précédente pour détecter les relations de cohésion (dépendances logiques
internes) et de couplage (dépendances logiques externes).
Dans le chapitre suivant, nous allons présenter l’implémentation de notre proposition, ainsi que
les expérimentations effectuées dans le but de prouver à quel point notre approche est faisable et
efficace.
Chapitre I : Introduction Générale
CHAPITRE V
IMPLEMENTATION ET EXPERIMENTATION
VI.1 Introduction
Dans ce chapitre nous présentons la mise en œuvre de notre approche d’analyse de modularité des
logiciels OO. Nous avons réalisé un outil Java « Logical Modularity Analyser » contenant deux sous-
outils : un pour la génération des règles d’association en se basant sur l’algorithme Apriori, et un deuxième
qui a comme objectif la génération des relations de couplage et de cohésion logiques.
Les résultats obtenus par notre outil facilitent l’analyse de modularité pour le développeur de logiciel OO.
Ce dernier peut décider si le logiciel nécessite une simple restructuration, ou même un refactoring pour
obtenir une version plus modulaire.
Notre outil est validé à travers des expérimentations afin de prouver son efficacité. Nous avons analysé
les dépôts de versions de trois applications Java Open-source de grande taille.
En vue d’analyser l’historique de l’évolution d’un logiciel OO, nous sommes chargés en premier lieu
d’extraire ses diverses versions depuis son dépôt de versions. Nous avons désigné le dépôt Github
précisément en raison de sa richesse, sa réputation et sa célébrité. Ce dernier est connu comme une
plateforme sur le web à distribuer plusieurs applications et ses codes source du projet.
Principe
Cette étape répond à la question : « Qu'est-ce qui a vraiment changé entre deux versions du logiciel OO
? ». De ce fait, nous avons utilisé un outil vigoureux afin d’effectuer la comparaison du code source Java.
Cet outil est « JDiff » basé sur doclet Javadoc qui émet un rapport de tous les packages, classes, méthodes,
etc., qui sont changés (la partie "diff") lorsque deux API Java sont comparées. Idéal pour signaler ce qui a
changé entre deux versions ; qui produit un rapport décrivant exactement les changements précis entre deux
versions d'un logiciel OO [JDI20].
Les Doclets sont des programmes qui fonctionnent avec l’outil Javadoc pour générer des documents à
partir du code écrit en Java.
Dans ce domaine, nous trouvons différents mécanismes de différenciation. Parmi ces outils nous avons
désigné JDiff en raison des avantages ci-dessous [CHR11] :
Quel que soit le niveau de granularité : packages, classes, méthodes ; JDiff peut décrire parfaitement
ce qui a changé dans chaque version du logiciel.
Il est basé sur Javadoc standard aussi simple et rapide dans son utilisation.
Chapitre I : Introduction Générale
La plupart des outils de comparaison de fichiers de code source exercent une différenciation
textuelle. Ils prennent en considération n'importe quel changement dans le texte du fichier. il en
résulte que même les changements qui ne touche pas vraiment le fonctionnement du code source sont
détectés, par exemple : les commentaires. En revanche, JDiff est utilisé spécialement dans la
différenciation entre les fichiers Java en appliquant une différenciation sémantique et en éliminant
les changements qui ne touchent pas le déroulement du logiciel. [BOU19].
Facile à intégrer dans d’autres outils à cause de l’utilisation en ligne de commande.
Possibilité de sa configuration pour réaliser une différentiation particulière d’un objectif ciblé car
JDiff est un outil Open-Source.
JDiff a la possibilité d’avoir un rapport en format XML (Extensible Markup Language) qui est
facile dans son analyse prochainement dans les phases de notre approche.
Précepte de déroulement de JDiff
JDiff utilise l'API de doclet Javadoc, qui offre aux développeurs de doclet une arborescence prête à
l'emploi et facile à utiliser de tous les packages et les classes Java des fichiers analysés par Javadoc.
Le doclet JDiff a deux modes de fonctionnement :
Dans le premier mode, il agit comme un doclet générant du XML qui traverse tous les packages et
les classes de l'application et écrit autant d'informations dans un fichier XML.
Le deuxième mode de fonctionnement utilise deux fichiers XML de ce type en tant qu'entrée dans un
analyseur XML, tel que l'analyseur XML Xerces, et les compare soigneusement. Les résultats de la
comparaison sont ensuite utilisés par un certain nombre de classes JDiff pour générer la sortie XML
en détectant tous les types de changements entre deux versions d'un projet Java.
Chaque changement dans l'application Java est signalé, des nouvelles méthodes, champs, ou
changements dans les types de paramètres et les exceptions levées . . . etc. [JDI20].
Pour l’extraction des transactions de changement, chaque deux versions d’un projet Java doivent être
différenciées. C’est pourquoi, nous avons appliqués l’outil « JDiff ». Par ailleurs, et dans le but d’appliquer
l’algorithme Apriori sur les transactions de changement générées par JDiff, nous avons exigés de les
formater au maximum en vue de garder seulement les informations indispensables au Mining. Nous sommes
censés de laisser dans chaque transaction uniquement les classes changées ainsi que les packages auxquels
elles s'affilient.
Dans la mesure où JDiff est un outil Open-source, nous l'avons configuré pour générer un rapport XML
englobant ce que nous avons exigé précisément pour le Mining i.e. les classes changées entre les deux
versions.
Chapitre I : Introduction Générale
En supplément, nous avons configuré JDiff pour faire la différenciation entre toutes les versions du dépôt
de l'application Java (N versions) d’une manière automatique. Le résultat est un seul rapport XML contenant
toutes les transactions de changement. Ce rapport sera prêt à être analysé facilement avec l'algorithme
Apriori.
Nous pouvons subdiviser l’algorithme qui génère les règles d’association en deux phases principales :
1. Extraction des itemsets fréquents
C’est la détermination de l’ensemble des itemsets fréquents dans la base de transaction. À la
lumière de cette approche, nous avons implémenté l'algorithme Apriori avec le langage Java. Ce
programme génère des dépendances logiques à partir des transactions de changement. Par
conséquent, il analyse le rapport XML généré dans l'étape précédente (la différenciation). À
posteriori, nous présenterons le principe de fonctionnement de cet algorithme tout en éclaircissons
ses distinctes fonctions essentielles.
Nous avons un fichier XML nommé « transaction.xml » (Listing V.1) qui fournit la structure du
fichier XML englobant les transactions de changement. Dans cette partie, nous devons fixer un
support minimum (minsup) et une confidence minimale (minconf).
1. public AprioriCalculation(String data, int numItems, int numTransaction
s,
2. double minSup, double confidence) throws IOException {
3. this.data = data;
4. this.numItems = numItems;
5. this.numTransactions = numTransactions;
6. this.minSup = minSup /= 100.0;
Chapitre I : Introduction Générale
7. this.confidence = confidence;
8. oneVal = new String[numItems];
9. for (int i = 0; i < numItems; i++) {
10. oneVal[i] = "1";
11. }
12. FileWriter fw;
13. BufferedWriter file_out;
14. fw = new FileWriter(outputFile);
15. file_out = new BufferedWriter(fw);
16. file_out.write(numTransactions + "\n");
17. file_out.write(numItems + "\n******\n");
18. file_out.close(); }
1. <?xml version="1.0" encoding="UTF-8"?>
2. <rules><rule confidence="0.7" support="0.3333333333333333" id="0"><anteceden
t>
3. <item package="org.traccar">MainEventHandler</item></antecedent><consequent>
<item
4. package="org.traccar.database">IdentityManager</item></consequent></rule>
5. <rule confidence="0.875" support="0.3333333333333333" id="1"><antecedent><it
em
6. package="org.traccar.database">IdentityManager</item></antecedent><consequen
t>
7. <item package="org.traccar">MainEventHandler</item></consequent></rule>
8. <rule confidence="0.6" support="0.2857142857142857" id="2"><antecedent><item
9. package="org.traccar">MainEventHandler</item></antecedent><consequent><item
10. package="org.traccar.protocol">HuabaoProtocolDecoder</item></consequent></ru
le>
Chapitre I : Introduction Générale
11. <rule confidence="0.8571428571428571" support="0.2857142857142857" id="3">
12. <antecedent><item package="org.traccar.protocol">HuabaoProtocolDecoder</item
>
13. </antecedent><consequent><item package="org.traccar">MainEventHandler</item>
14. </consequent></rule>
15. ….
16. </rules>
La figure V.3 présente l’interface graphique principale de notre application. Elle affiche les opérations
primordiales à effectuer :
Chargement du fichier de transactions.
Génération des règles d’association.
Génération des règles internes (cohésion) et les règles externes (couplage).
Dans ce qui suit, nous allons bien détaillés chaque opération avec sa propre fenêtre.
La figure V.4 illustre l'interface graphique qui permet au développeur de générer les règles d'association à
partir d'une base de transactions sauvegardé antérieurement dans le fichier « transaction.xml ». Tout
Chapitre I : Introduction Générale
d’abord, le développeur doit fixer un support et une confidence minimaux. Le résultat sera le fichier
« Rules.xml » qui sera enregistré dans le répertoire de notre application.
C. Couplage et cohésion
Cette phase est la plus importante dans notre approche. Elle constitue la base de l’analyse de la modularité
du logiciel OO avec notre outil « Logical Modularity Analyser ». À ce niveau-là, le développeur charge
l’ensemble des règles d’association en fixant un support et une confidence minimaux. Le résultat trouvé sera
dispatché en deux grands titres :
Le premier indique la cohésion qui illustre les règles logiques internes reliant les classes dans le
même package du logiciel OO. Dans ce cas, nous pouvons sélectionner dans la liste déroulante tous
les packages pour afficher toutes les règles logiques internes ou bien celles qui concernent seulement
un package désiré par le développeur.
Le deuxième représente le couplage qui indique l’ensemble des règles logiques externes reliant les
différents packages de l’application. Idem pour la liste de choix, nous pouvons sélectionner le nom
du package et une opération de filtrage vas nous donner seulement les règles logiques externes qui
Chapitre I : Introduction Générale
peut contenir ce package quel que soit dans la partie Antécédents ou Conséquents.
À la fin de chaque procédure il y aura une force ‘strength’ qui est considéré comme un repère
indiquant le niveau de la modularité du logiciel OO ; qui est le support de chaque règle. Le résultat trouvé
sera enregistré dans deux fichiers XML, un pour les relations logiques internes « Cohésion.xml » et l’autre
pour les relations logiques externes « Couplage.xml ».
VI.3 Expérimentations
Dans cette partie, c’est notre tour de prouver la faisabilité, la fiabilité, et l’efficacité de notre projet. Nous
avons appliqué notre approche sur trois cas d'étude. Dans les sections qui suivent, nous allons détailler ces
cas en présentons leurs descriptions et les résultats obtenus.
N Nombre de ligne de
Numéro de version Nombre de package Nombre de classe
° code
01 traccar-3.0 8 258 16360
02 traccar-3.1 8 341 13491
03 traccar-3.2 8 388 14114
04 traccar-3.3 11 428 15289
05 traccar-3.4 11 444 15732
06 traccar-3.5 11 459 16231
07 traccar-3.6 13 493 17609
08 traccar-3.7 16 539 20011
09 traccar-3.8 16 579 22096
10 traccar-3.9 16 590 22599
11 traccar-3.10 17 621 23954
12 traccar-3.11 18 642 25035
13 traccar-3.12 19 686 26902
14 traccar-3.13 19 687 26917
15 traccar-3.14 19 696 27367
16 traccar-3.15 19 726 29014
17 traccar-3.16 19 742 29465
18 traccar-3.17 19 772 30930
19 traccar-4.0 21 810 31741
20 traccar-4.1 21 830 31826
21 traccar-4.2 21 837 32118
22 traccar-4.3 21 852 33260
23 traccar-4.4 22 874 34725
24 traccar-4.5 22 879 34813
Tableau V-00-4: Métriques de l'application Traccar avec Iplasma.
Suite à l’étape de différenciation en utilisant JDiff, les transactions de changement sont générées et
enregistrées dans un fichier XML. Ces transactions sont analysées suivant la première phase de notre
approche, en fixant un support minimum de 15% et une confidence à 100%. Le résultat trouvé après la
génération des règles d’association est plus que 331 règles comme nous montre la figure V.6.
Chapitre I : Introduction Générale
Nous avons mis la structure des règles d’association générées dans le listing suivant :
1. <?xml version="1.0" encoding="UTF-8"?>
2. <rules>
3. <rule confidence="1.0" support="0.19047619047619047" id="0"><antecedent><item
package="org.traccar.database">LdapProvider</item></antecedent><consequent><it
em package="org.traccar">MainEventHandler</item></consequent></rule>
4. <rule confidence="1.0" support="0.23809523809523808" id="1"><antecedent><item
package="org.traccar.web">WebServer</item></antecedent><consequent><item packa
ge="org.traccar">MainEventHandler</item></consequent></rule>
5. …….
6. <rule confidence="1.0" support="0.19047619047619047" id="330"><antecedent><ite
m package="org.traccar.protocol">WatchFrameDecoder</item></antecedent><consequ
ent><item package="org.traccar.geocoder">AddressFormat</item><item package="or
g.traccar.model">User</item><item package="org.traccar.notification">JsonTypeE
ventForwarder</item><item package="org.traccar.model">Server</item></consequen
t></rule>
7. <items minsup="0.15" minconf="100.0">LdapProvider, WebServer, Checksum, Meitra
ckProtocol, Position, Gt06ProtocolDecoder, Group, WrapperInboundHandler, Serve
r, WatchFrameDecoder, CommandsManager, JsonTypeEventForwarder, MainEventHandle
r, IdentityManager, HuabaoProtocolDecoder, WatchProtocolEncoder, AddressFormat
, User, KhdProtocolDecoder, CharacterDelimiterFrameDecoder</items>
8. </rules>
Dans la dernière ligne dans chaque fichier « Rules.xml », nous avons met l’ensemble des itemsets
fréquents, contenant un minimum support et une minimale confidence i.e. l’ensemble des classes
fréquemment changées.
Ce niveau est considéré comme le noyau de notre approche. Maintenant, nous pouvons extraire les
relations logiques internes avec un support minimal de 0.1 et une confidence de 1 et extraire les relations
logiques externes avec les mêmes mesures. Finalement, l’outil affiche cinq relations logiques internes pour
la cohésion et 326 relations logiques externes pour le couplage.
Le résultat trouvé sera enregistré dans deux fichiers XML différents. L’un sera nommé « cohésion.xml »
et l’autre « couplage.xml » comme nous montre le Listing V.5 et Listing V.6.
1. <?xml version="1.0" encoding="UTF-8"?>
2. <rules>
3. <rule confidence="1.0" id="5" support="0.19047619047619047"><antecedent><item package="
org.traccar.database">LdapProvider</item></antecedent><consequent><item package="org.tr
accar.database">IdentityManager</item></consequent></rule>
4. <rule confidence="1.0" id="10" support="0.19047619047619047"><antecedent><item package=
"org.traccar">WrapperInboundHandler</item></antecedent><consequent><item package="org.t
raccar">CharacterDelimiterFrameDecoder</item></consequent></rule>
5. <rule confidence="1.0" id="15" support="0.23809523809523808"><antecedent><item package=
"org.traccar.model">Position</item></antecedent><consequent><item package="org.traccar.
model">User</item></consequent></rule>
6. <rule confidence="1.0" id="17" support="0.19047619047619047"><antecedent><item package=
"org.traccar.model">Group</item></antecedent><consequent><item package="org.traccar.mod
el">User</item></consequent></rule>
7. <rule confidence="1.0" id="18" support="0.23809523809523808"><antecedent><item package=
"org.traccar.model">Server</item></antecedent><consequent><item package="org.traccar.mo
del">User</item></consequent></rule>>
8. </rules>
1. <?xml version="1.0" encoding="UTF-8"?>
2. <rules>
3. <rule confidence="1.0" id="0" support="0.19047619047619047"><antecedent><item
package="org.traccar.database">LdapProvider</item></antecedent><consequent><it
Chapitre I : Introduction Générale
em package="org.traccar">MainEventHandler</item></consequent></rule>
4. <rule confidence="1.0" id="1" support="0.23809523809523808"><antecedent><item
package="org.traccar.web">WebServer</item></antecedent><consequent><item packa
ge="org.traccar">MainEventHandler</item></consequent></rule>
5. …
6. <rule confidence="1.0" id="329" support="0.19047619047619047"><antecedent><ite
m package="org.traccar.model">Server</item><item package="org.traccar.protocol
">WatchFrameDecoder</item></antecedent><consequent><item package="org.traccar.
geocoder">AddressFormat</item><item package="org.traccar.model">User</item><it
em package="org.traccar.notification">JsonTypeEventForwarder</item></consequen
t></rule>
7. <rule confidence="1.0" id="330" support="0.19047619047619047"><antecedent><ite
m package="org.traccar.protocol">WatchFrameDecoder</item></antecedent><consequ
ent><item package="org.traccar.geocoder">AddressFormat</item><item package="or
g.traccar.model">User</item><item package="org.traccar.notification">JsonTypeE
ventForwarder</item><item package="org.traccar.model">Server</item></consequen
t></rule>>
8. </rules>
13 bco.bcozy-1.4.6 13 48 1418
14 bco.bcozy-1.5.0 18 62 1672
15 bco.bcozy-1.5.1 18 62 1672
16 bco.bcozy-1.6.0 18 62 1672
17 bco.bcozy-1.6.1 18 62 1662
18 bco.bcozy-1.6.2 18 59 1504
19 bco.bcozy-1.6.3 18 59 1504
20 bco.bcozy-1.6.4 18 59 1407
Tableau V-00-5: Métriques de l'application bco.bcozy avec Iplasma.
Résultat
Nous avons fixé une valeur minimale de 25% pour le support, et pour la confidence sa valeur minimale
fixée est de 100%. Suite de la génération des règles d’association, nous avons découvrit 1543 règles. La
figure V.8 Montre ce résultat.
La structure des règles d’association générées pour Bco.Bcozy est présentée comme suit :
1. <?xml version="1.0" encoding="UTF-8"?>
2. <rules>
3. <rule confidence="1.0" support="0.3333333333333333" id="0"><antecedent><item p
ackage="org.openbase.bco.bcozy.model">LanguageSelection</item></antecedent><co
nsequent><item package="org.openbase.bco.bcozy.util">AuthorizationGroups</item
></consequent></rule>
4. <rule confidence="1.0" support="0.3333333333333333" id="1"><antecedent><item p
ackage="org.openbase.bco.bcozy.util">AuthorizationGroups</item></antecedent><c
onsequent><item package="org.openbase.bco.bcozy.model">LanguageSelection</item
></consequent></rule>
5. …….
Chapitre I : Introduction Générale
6. <rule confidence="1.0" support="0.3333333333333333" id="1542"><antecedent><ite
m package="org.openbase.bco.bcozy.controller">UserSettingsController</item></a
ntecedent><consequent><item package="org.openbase.bco.bcozy.model">LanguageSel
ection</item><item package="org.openbase.bco.bcozy.util">AuthorizationGroups</
item><item package="org.openbase.bco.bcozy.util">BundleLanguagesDetector</item
><item package="org.openbase.bco.bcozy.view">FloatingButton</item><item packag
e="org.openbase.bco.bcozy.view.pane.unit">AbstractUnitPane</item><item package
="org.openbase.bco.bcozy.view.pane.unit">ColorableLightPane</item></consequent
></rule>
7. <items minsup="0.25" minconf="100.0">LanguageSelection, AuthorizationGroups, B
undleLanguagesDetector, FloatingButton, AbstractUnitPane, ColorableLightPane,
UserSettingsController, LoadingPane, UserActionPane.State</items>
8. </rules>
L’application de notre outil « Logical Modularity analyser » (Figure V.9) avec un support minimal de
0.1 et une confidence de 1 pour extraire les relations logiques internes et externes, nous induit plus de
quatre relations logiques internes pour la cohésion et 1539 relations logiques externes pour le couplage.
Résultats
Dans ce cas, nous avons fixé un support minimum de 10% et la confidence de 100%. Au-delà de la
génération des règles d’association, nous avons détecté neuf règles (Figure V.10).
Chapitre I : Introduction Générale
L’ensemble des règles d’association et les itemsets fréquents sont illustrés dans ce listing :
1. <?xml version="1.0" encoding="UTF-8"?>
2. <rules>
3. <rule confidence="1.0" support="0.125" id="0"><antecedent><item package="teamm
ates.ui.controller">InstructorFeedbackCopyAction</item></antecedent><consequen
t><item package="teammates.storage.api">FeedbackQuestionsDb</item></consequent
></rule>
4. …..
5. <rule confidence="1.0" support="0.125" id="8"><antecedent><item package="teamm
ates.ui.controller">InstructorFeedbackCopyAction</item><item package="teammate
s.ui.controller">StudentFeedbackSubmissionEditPageAction</item></antecedent><c
onsequent><item package="teammates.storage.api">FeedbackQuestionsDb</item></co
nsequent></rule>
6. <items minsup="0.1" minconf="100.0">InstructorFeedbackCopyAction, Const, Instr
uctorPrivileges, TimeHelper, FeedbackQuestionsDb, StudentFeedbackSubmissionEdi
tPageAction</items>
7. </rules>
Notre outil « Logical Modularity analyser » (figure V.11) s’est appliqué avec un support minimal de
0.1 et une confidence de 1 pour extraire les relations logiques internes et externes, nous induit une seule
relation logiques internes pour la cohésion et huit relations logiques externes pour le couplage.
Après l’application de divers scénarios d’analyse sur les trois logiciels depuis NetBeans, nous avons
constaté que notre outil est un appui pour la génération des transactions, les règles d’association ainsi que
des règles logiques internes (cohésion) et des règles logiques externes (couplage).
<rule confidence="1.0" id="6" support="0.3333333333333333"><antecedent><item package="org.trac
car.helper">Checksum</item></antecedent><consequent><item package="org.traccar">MainEventHandl
er</item></consequent></rule>
Listing V-10: Exemple d’une règle logique de l’application Traccar.
Pour effectuer la comparaison, nous avons pris un zoom-in dans le graphe des dépendantes statiques de
cet exemple (figure V-12). Nous avons découvert que cette règle n’existe pas dans le graphe.
V.4 Conclusion
Dans ce chapitre, nous avons présenté la mise en œuvre des différentes phases de notre approche : la
génération des règles d’association, la production des règles logiques internes nommé « cohésion » et des
règles logiques externes « couplage » avec un minimum support et une minimum confidence.
Nous avons automatisé ces étapes via notre outil « logical modularity Analyzer ». Par la suite, nous avons
analysé trois cas d’étude dans le but de manifester la fiabilité et l’efficience de notre suggestion pour évaluer
et analyser la modularité logique des logiciels OO. Les aboutissements et les performances ont été très
encourageants.
Le chapitre suivant clôture notre mémoire, en présentant les contributions de notre travail et ses
perspectives.
Chapitre I : Introduction Générale
Chapitre I : Introduction Générale
Chapitre VI
Conclusion & Perspectives
L’évolution des grands systèmes logiciels OO dégraderait et modifierait avec le temps, sa structure et sa
modularité. Par conséquent, parmi les principaux problèmes en génie logiciel, l’analyse et l’évaluation de la
modularité du système logiciel présente un vrai défi i.e. le logiciel OO évolué a-t-il encore une modularité
adéquate ? Sinon, c’est quoi les défauts de modularités existants ? En revanche, l'automatisation de cette
tâche offre une assistance énorme aux développeurs. Afin d’atteindre cet objectif, nous nous sommes basées
sur un type intéressant de dépendances connues par les dépendances logiques en vue de proposer notre
approche d’analyse de la modularité des logiciels OO.
VI.1 Contribution
A travers notre travail, nous avons approuvé et déduit les avantages primordiaux des dépendances
logiques extraites à partir d’un dépôt de versions du logiciel, pour aider le développeur à identifier son
niveau de modularité et détecter les éventuelles parties touchées par un défaut de modularités.
Notre objectif principal était l’automatisation des tâches de l’analyse de la modularité logique dans le but de
faciliter et soutenir considérablement cette analyse pour le développeur. Nous pouvons synthétiser les
contributions fondamentales de notre travail dans les points suivants :
L’analyse du dépôt de versions d'un système logiciel OO afin de générer les dépendances logiques
entre ses classes :
Extraction des transactions de changement.
La génération des règles d'association en utilisant l'algorithme Apriori.
Le stockage des règles d'association dans une BDD accessible par notre outil d'analyse.
Nous avons proposé une approche basée sur les dépendances logiques pour analyser la modularité
logique du logiciel OO. Cette analyse permet de détecter les relations de cohésion logique et de
couplage logique pour chaque package.
L’automatisation des tâches précitées à travers notre outil réalisé par le langage Java, nous a facilité
l’analyse de la modularité de grands systèmes logiciels OO.
Dans l'intention de prouver la faisabilité et l’efficacité de notre approche proposée ; nous avons analysé
les dépôts de versions de trois applications OO Open-source de grande taille. Les résultats trouvés étaient
très encourageants car notre outil automatise convenablement les fonctions de la génération des règles
d’association, l’analyse de la modularité logique et la détection les défauts de modularité.
Chapitre I : Introduction Générale