Utilisateur:Alapide romuald/Brouillon

Détection automatique d'anti-patrons dans les logiciels à architecture orientée objet.

La détection automatique (ou semi-automatique) d'anti-patrons ou défauts de patrons[1] (anti-patterns, en anglais) dans les logiciels à architecture orientée objet est un sujet récent de la recherche dans le domaine informatique. Les premiers travaux d'automatisation de cette tâche coûteuse en temps et en analystes expérimentés commencent en effet seulement en 2004 avec la publication des travaux d'un chercheur roumain, Radu Marinescu.

Les anti-patrons sont de mauvaises applications des solutions des patrons de conception[1] (design patterns, en anglais). Ces anti-patrons ont un impact négatif fort sur des attributs de qualité du logiciel tels que la flexibilité et la maintenabilité.[2]

Une approche automatisée de la détection de ces problèmes est nécessaire car bien souvent les logiciels, au fil des années, deviennent imposants (plusieurs dizaines de millions de lignes de code pour Eclipse par exemple). Les coûts nécessaires à la détection manuelle des anti-patterns et leurs corrections seraient astronomiques. C'est pourquoi depuis une dizaine d'années, des chercheurs en informatique du monde entier travaillent sur des techniques de détection automatique, et parfois également de correction automatique, des anti-patrons dans les logiciels à architecture orientée objet.

Cette article présente de façon chronologique différentes solutions qu'a apporté la recherche à ce besoin.

Etat de l'art de la détection automatique et semi-automatique des anti-patterns dans les logiciels à architecture orientée objet

modifier

Ne sont détaillés ici que les méthodes ayant été implémentées, validées et étant reproductibles. Ainsi, le travail de Alikacem et al. dans Alikacem et al., 2006 ne sera pas abordé car l'approche qu'il propose n'a jamais été validé. Le travail de Marinescu dans [Marinescu, 2004], bien que précurseur, ne sera pas non plus abordé car sa méthode comporte des zones d'ombres qui rendent impossible la reproduction de son travail.

DETEX (DETextion EXpert)

modifier

DETEX [Moha et al., 2010] est une technique de détection semi-automatique pour les défauts de code et de conception. Elle fait partie d'une méthode plus importante de détection et de correction automatique des défauts de code (code smells, en anglais) et des défauts de conception (anti-patterns, en anglais) nommée DECOR.

Principes
modifier

La méthode DETEX commence par considérer que les défauts de conception peuvent être décrits selon une taxonomie bien défini[1].

A partir de cette taxonomie, l'ingénieur pourra alors définir des combinaisons de règles (beaucoup de lignes dans une méthodes, beaucoup de méthodes dans une classe, etc.) constituant les caractéristiques d'un défaut de conception dans un DSL conçu pour l'occasion sous forme d'une fiche de règles avec une grammaire BNF.

Ce DSL sera ensuite analysé et transformé en un méta-modèle plus adapté aux traitements informatiques pour générer automatiquement, à partir de ce méta-modèle, les algorithmes capables de détecter les défauts de conception décrits dans les fiches de règles définies auparavant.

En dernier lieu, ces algorithmes générés seront exécutés sur un méta-modèle extrait, automatiquement par rétro-ingénierie, du code à analyser pour en extraire les classes répondant à la description de (ou des) l'anti-patron(s) recherché(s).

Objectifs
modifier

En s'appuyant sur les travaux précédents ([Marinescu, 2004] et [Alikacem et al., 2006]), Moha et al. ont voulu fournir une méthode de détection des défauts de conception la plus automatisée possible, itérative, flexible, simple d'utilisation (pas besoin de comprendre comment cela fonctionne pour pouvoir l'utiliser), réutilisable, extensible, précise et efficace. Mais également une méthode complètement détaillée et reproductible, ce qui manquait dans les précédents travaux.

Fonctionnement
modifier

A partir d'une analyse détaillée des descriptions textuelles des défauts de conception de la littérature de la méthode DETEX devra dans un premier temps identifier, définir et organiser manuellement les concepts-clefs utilisés pour décrire les anti-patrons qu'il souhaite détecter. Ces concepts-clefs peuvent être regroupés selon les auteurs dans quatre catégories :

  • Les propriétés mesurables : sont des concepts exprimés avec des mesures d'attributs (métriques) internes des entités d'un système (classe, interface, méthodes, attributs, relations, etc.) telles que la taille des classes ou le nombre de paramètres d'une méthode.
  • Les propriétés lexicales : correspondent au vocabulaire utilisé pour nommer les entités. Elles caractérisent les entités avec des noms spécifiques définis dans des listes de mots-clés ou dans un thésaurus documentaire.
  • Les propriétés structurelles : définissent les structures des entités (par exemple, des attributs correspondant à des variables globales).
  • Les relations structurelles : définissent les relations des entités (par exemple, une relation d'association entre deux classes).

Par exemple, pour l'anti-patron Spaghetti Code : les propriétés mesurables incluent les concepts de longues méthodes, de méthodes sans paramètres, d’héritage; les propriétés lexicales incluent les concepts de noms procéduraux; les propriétés structurelles incluent les concepts de variables globales et de polymorphisme. [Moha et al., 2010]

Les auteurs ont déjà fait une grosse partie de ce travail en construisant une taxonomie comportant 8 anti-patrons et 21 défauts de code. Ceux-ci étant définis par plus de 60 concepts-clefs réutilisables pour définir d'autres anti-patrons.

Dans une seconde étape, l'utilisateur doit spécifier, dans un DSL produit pour DETEX, les défauts de manière déclarative sous forme de compositions de règles dans des fiches de règles. Ainsi, chaque anti-patron de la taxonomie est décrit dans une fiche de règle. Chaque règle représentant un défaut de code.

Le DSL formalise la spécification des fiches de règles avec la grammaire BNF suivante (les numéros devants les lignes ne sont que les numéros de lignes) :

1          rule card ::= RULE CARD:rule cardName { (rule)+ };

2     rule ::= RULE:ruleName { content rule };

3     content rule ::= operator rule rule | property | relationship

4     operator ::= INTER | UNION | DIFF | INCL | NEG

5     property ::= METRIC id metric metric value fuzziness

6                 | LEXIC id lexic ((lexic value,)+)

7                 | STRUCT id struct

8     id metric ::= DIT | NINTERF | NMNOPARAM | LCOM | LOC METHOD | LOC CLASS | NAD | NMD | NACC | NPRIVFIELD

9                                  | id metric + id metric

10                                | id metric - id metric

11        value metric ::= VERY HIGH | HIGH | MEDIUM | LOW | VERY LOW | NUMBER

12        id lexic ::= CLASS NAME | INTERFACE NAME | METHOD NAME | FIELD NAME | PARAMETER NAME

13        id struct ::= USE GLOBAL VARIABLE | NO POLYMORPHISM | IS DATACLASS | ABSTRACT CLASS | ACCESSOR METHOD | FUNCTION CLASS | FUNCTION METHOD | STATIC METHOD | PROTECTED METHOD   14                  | OVERRIDDEN METHOD | INHERITED METHOD | INHERITED VARIABLE

15        relationship ::= rel name FROM rule cardinality TO rule cardinality

16        rel name ::= ASSOC | AGGREG | COMPOS

17        cardinality ::= ONE | MANY | ONE OR MANY | OPTIONNALY ONE

18        rule cardName, ruleName, lexic value ∈ string

19        fuzziness ∈ double


Ce qui donne par exemple pour pour l'anti-patron Spaghetti Code, la fiche suivante :

1          RULE CARD:SpaghettiCode {

2              RULE:Inter0

                  {INTER Inter1 Inter2};

3              RULE:Inter1

                  {INTER LongMethod NoParameter};

4              RULE:LongMethod {METRIC LOC METHOD VERY HIGH 10.0};

5              RULE:NoParameter {METRIC NMNOPARAM VERY HIGH 5.0};

6              RULE:Inter2

                  {INTER Inter3 Inter4};

7              RULE:Inter3

                  {INTER NoInheritance NoPolymorphism};

8              RULE:NoInheritance {METRIC DIT 1 0.0};

9              RULE:NoPolymorphism {STRUCT NO POLYMORPHISM};

10            RULE:Inter4

                  {INTER ProceduralName UseGlobalVariable};

11            RULE:ProceduralName {LEXIC CLASS NAME (Make, Create, Exec...)};

12            RULE:UseGlobalVariable {STRUCT USE GLOBAL VARIABLE};

13        };

L'étape suivante est la génération automatique des algorithmes de détection à partir des fiches de règles établies par l'utilisateur. La plateforme logiciel se chargeant de ce travail transforme dans un premier temps les fiches de règles en méta-modèles, qui sont validés puis envoyés au générateur d'algorithmes pour enfin aboutir sur le code de ces algorithmes de détection. (la méthode de génération étant plus détaillée dans [Moha et al., 2010])

Enfin la dernière étape de DETEX est d'exécuter les algorithmes générés sur les méta-modèles PADL[3] préalablement extrait automatiquement par rétro-ingénierie du code à analyser. Cette exécution nous retournant la liste des classes détectées comme répondant aux critères des fiches de règles.

BBNs based detection 

modifier
Principes
modifier

L'approche de [Khomh et al., 2009] se base sur les réseaux bayésiens (bayesian networks ou bayesian belief networks ou BBNs, en anglais) pour spécifier les défauts de conception et pour les détecter dans les programmes.

Objectifs
modifier

L'objectif de cette approche est d'améliorer les résultats des précédentes méthodes, toutes utilisant des règles basées sur des métriques, et en particulier améliorer les résultats de DECOR. Ces améliorations sont de plusieurs natures :

  • DECOR n'est pas capable de traiter l'incertitude. C'est à dire que pour elle, soit une classe (ou un ensemble de classes) est un potentiel anti-patron soit elle ne l'est pas. Ici, avec les BBNs nos résultats sont des probabilités qu'une classe (ou un ensemble de classes) soit un anti-pattern.
  • Le fait que les résultats soient des probabilités permettra de mieux guider les experts en charge de la vérification des résultats de l'analyse. En effet, une classe qui a 90% de risque d'être un BLOB par exemple, va plus attirer l’œil qu'une classe n'ayant que 20% de risque. Cela accélérera donc également la vitesse de correction potentiel.
  • Comme il est souligné dans la théorie bayésienne, un BBN peut être calibré ou re-calibré (et donc amélioré) en utilisant les résultats des analyses précédentes. Cela permet de d'améliorer les performances de détection des BBN pour des contextes données (e.g. organisation et type de programme).
  • Un expert en ingénierie logiciel pourra calibrer le BBN pour améliorer ses résultats de détection.
Fonctionnement
modifier

Un BBN est un graphe orienté acyclique qui représente une distribution de probabilités. Dans ce graphe, chaque variable aléatoire Xi est représentée par un nœud. Une arête orientée entre deux nœuds indique une dépendance probabiliste venant de la variable du nœud parent et allant vers la variable du nœud enfant. Ainsi, la structure du réseau désigne l’hypothèse que chaque nœud Xi dans le réseau est seulement dépendant conditionellement de ses parents. Chaque nœud Xi est associé à un tableau de probabilités conditionnelles qui spécifie la distribution des probabilités pour tous de ses possibles valeurs, pour chaque combinaisons possibles de valeurs de ses nœuds parents. Pour que cette définition soit plus explicite, un bonne exemple est donné ici.

Donc, un BBN est composé de deux choses :

  • une structure composée de nœuds et d'arcs orientés qui forment un réseau.
  • un tableau contenant des conditions et des probabilités liées à ces conditions.

Pour fabriquer la structure du réseau dans notre cas de détection de défauts de conception, plusieurs options s'offrent à nous :

  • étudier les heuristiques de la littérature
  • utiliser les fiches de règles définies dans la méthode DECOR car celles-ci sont déjà une synthèse des heuristiques définissants les anti-patrons de la littérature.

La seconde option est le choix des auteurs. Cette transformation des fiches de règles en un BBN est réalisée en deux étapes :

  1. ils transforment les propriétés d'entrées (propriétés mesurables, propriétés lexicales et propriétés structurelles) en nœuds d'entrée (nœuds d'où partent les arcs initiaux) avec des distributions de probabilités.
  2. ils transforment l'ensemble des opérateurs de la fiche de règle en nœuds de décision (nœuds où se rejoignent des arcs) possédants des tableaux de probabilités conditionnelles.

Ainsi, par exemple, la fiche décrivant la GOD Class (ou BLOB) suivante :

1       RULE_CARD : Blob {

2              RULE : Blob { ASSOC: associated FROM: mainClass ONE TO: DataClass MANY };

3              RULE : MainClass { UNION LargeClassLowCohesion ControllerClass };

4              RULE : LargeClassLowCohesion { UNION LargeClass LowCohesion };

5              RULE : LargeClass { (METRIC: NMD + NAD, VERY_HIGH, 0) };

6              RULE : LowCohesion { (METRIC : LCOM5, VERY_HIGH , 20) };

7              RULE : ControllerClass { UNION

8                                (SEMANTIC: METHODNAME, {Process, Control, Ctrl, Command, Cmd, Proc, UI, Manage, Drive })

10                              (SEMANTIC: CLASSNAME, {Process, Control, Ctrl, Command, Cmd, Proc , UI, Manage, Drive, System, Subsystem })

11               };

12            RULE : DataClass { ( STRUCT: METHOD_ACCESSOR, 90) };

13   };

devient la structure et le tableau des distributions des probabilités suivant  :

  

Pour plus d'informations sur la technique de transformation et sur le reste de la méthode, je vous invite à aller lire l'article disponible libre ici : http://www.ptidej.net/publications/documents/QSIC09.doc.pdf. En effet, cette méthode est complexe et trop longue à expliquer ici.

A noter que la méthode a, depuis 2009, continué d'être développée au moins jusqu'en 2011 car ses auteurs dans [Khomh et al., 2011], ont sorti un second article se basant sur ce premier article en y ajoutant une approche par les buts ("Goal, Question, Metric" ou CQM, en anglais) pour construire les BBNs à partir des définitions des anti-patrons, nommé BDTEX.

ABS (Antipattern identification using B-Splines)

modifier
Principes
modifier

L'approche [Oliveto et al., 2010] est de se baser sur une technique d'analyse numérique utilisant une forme spécifique d'interpolation, les B-Splines, pour apporter une nouvelle technique de détection automatisée des défauts de conception.

Objectifs
modifier

Les auteurs ont identifié deux limitations principales dans les approches précédents la leur :

  • Soit ces approches classifient les classes de façon stricte comme étant ou non des anti-patterns. Elles ne peuvent donc pas identifier les classes étant très proches de la limite de la définition d'un anti-pattern (e.g., DECOR).
  • Soit elles retournent les probabilités que les classes soient des anti-patrons mais demandent alors beaucoup de travail manuel coûteux de la part d'experts pour obtenir des résultats satisfaisants (e.g., [Khomh et al., 2009]).

Oliveto et al. proposent donc une nouvelle approche d'identification automatique des défauts de conception pour outrepasser ces limites.

Fonctionnement
modifier

Pour chaque classe, on calcule un certain nombre de métriques. Avec toutes les valeurs des métriques d'une classe, on va calculer la "signature" de cette classe, sa B-spline, qui est une courbe (Les courbes de Bézier sont des B-splines). Puis on va calculer la distance de cette signature avec deux ensembles de signatures témoins. Le premier ensemble contenant les signatures des anti-patrons et le second contenant les signatures de classes dites "correctes" (qui ne font pas partie des anti-patrons). La conjecture de cette méthode est :

  • si une classe possède une signature similaire (distance faible entre deux signatures) à une des signatures contenues dans l'ensemble des signatures d'anti-patrons
  • et si cette signature est lointaine (distance importante entre deux signatures) des signatures de l'ensemble contenant les signatures des classes dites correctes
  • alors la classe qui est entrain d'être analysée est probablement un anti-pattern et est probablement l'anti-pattern dont la signature est proche.

Le principal obstacle à cette méthode est le manque potentiel de signatures témoins.

Principes
modifier

Cette nouvelle approche est basée sur une technique d'apprentissage automatique (machine learning en anglais), les machines à vecteurs de support (aussi appelées «  machines à support vectoriel », ou encore « séparateurs à vaste marge ». Support vector machines ou SVMs, en anglais) et est capable de prendre en compte le feedback de ses utilisateurs.

Objectifs
modifier

Les créateurs de cette méthode, voir [Maiga et Al., 2012], ont identifié quatre limitations dans toutes les méthodes détaillées précédemment :

  1. Elles requièrent des connaissances avancées des anti-patrons.
  2. Elles ont une précision et un rappel limité.
  3. Elles ne sont pas incrémentales.
  4. Elles ne peuvent pas être appliquées à un sous-ensemble d'un système. Pourtant cette fonctionnalité pourrait être très utile, par exemple sur les très gros systèmes comportant plusieurs millions de lignes de code. En effet, le parsing complet du code prendrait des heures voir des jours et la travail de correction qui s'en suivrait serait titanesque. Tandis que si l'on analyse une petite parcelle de cette immensité de code, cela facilitera la correction/suppression des défauts détectés. Cela pourrait également être très utile pendant le développement du logiciel car cela permettrait de ne pas avoir à attendre la fin du développement pour pouvoir lancer les premières analyses et amorcer les premières corrections.

L'objectif est donc de proposer une approche outrepassant ces limitations.

Fonctionnement
modifier

Le principe est simple tandis que le fonctionnement en lui-même est assez complexe car il faut maîtriser les concepts inhérents aux SVMs.

Le principe de SMURF est le suivant :

Prenons deux ensembles de données, l'un noté TDS (Training DataSet) et l'autre DDS (Demo DataSet). Le premier ensemble contient un ensemble de classes qui sont marquées comme étant ou non un anti-pattern (celui que nous souhaitons détecter) tandis que le second ensemble contient les classes qui nous voulons analyser.

La première étape de d’entraîner l'intelligence artificielle (IA) sur le dataset TDS. Pour cela, il faut d'abord extraire des métriques et leurs valeurs du code. Ensuite, l'IA est entraînée sur cette ensemble de métriques. Ici, elle va apprendre grâce aux marqueurs présent sur les classes à reconnaître l'anti-patron via ses métriques.

La seconde étape est maintenant d’exécuter l'IA entraînée sur le dataset DDS. Pour cela, même chose que sur le TDS, on extrait les métriques et leurs valeurs du code avec la même méthode. Puis l'IA est lancée sur les métriques. L'IA étant entraînée à reconnaître les classes représentant l'anti-patron recherché, elle va alors retourner toutes les classes qu'elle a détecté.

La troisième étape de la méthode consiste à donner un feedback à l'IA. En l'effet, l’utilisateur de la méthode doit maintenant marquer les classes retournées comme étant ou non des défauts de conception. L'utilisateur n'est pas obligé de toutes les marquer. Ce travail de marquage va ainsi donné un nouvelle ensemble d'entrainement pour l'IA, ce qui nous ramène donc à l'étape 1 de la méthode. Cette méthode est donc itérable à l'infini. L'utilisateur pourra donc entrainer l'IA autant qu'il le souhaitera de façon simple pour obtenir les meilleurs résultats possibles.

Notes et références

modifier

Bibliographie

modifier
  • [Albin-Amiot et al., 2002] Hervé Albin-Amiot, Pierre Cointe et Yann-Gaël Guéhéneuc, « Un méta-modèle pour coupler application et détection des design patterns. », Actes du 8e colloque Langages et Modèles à Objets, volume 8, numéro 1-2/2002 de RSTI – L’objet,‎ , p. 41-58
  • [Alikacem et al., 2006] El Hachemi Alikacem et Houari A. Sahraoui, « Détection d'anomalies utilisant un langage de règle de qualité. », LMO,‎ , p. 185-200 (lire en ligne)
  • [Fowler et al., 1999] (en) Martin Fowler, Kent Beck, John Brant, William Opdyke et Don Roberts, « Refactoring: Improving the Design of Existing Code. », Addison-Wesley,‎
  • [Khomh et al., 2009] (en) Foutse Khomh, Stéphane Vaucher, Yann-Gaël Guéhéneuc et Houari Sahraoui, « A Bayesian Approach for the Detection of Code and Design Smells », Quality Software, 2009. QSIC '09. 9th International Conference on,‎ , p. 305 - 314 (DOI 10.1109/QSIC.2009.47)
  • [Khomh et al. 2011] (en) Foutse Khomh, Stéphane Vaucher, Yann-Gaël Guéhéneuc et Houari Sahraoui, « BDTEX: A GQM-based Bayesian approach for the detection of antipatterns », The Ninth International Conference on Quality Software,‎ (DOI 10.1016/j.jss.2010.11.921)
  • [Maiga et al. 2012] (en) Abdou Maiga, Ali Nasir, Bhattacharya, Yann-Gaël Guéhéneuc et Esma Aïmeur, « SMURF: A SVM-based Incremental Anti-pattern Detection Approach. », 2013 20th Working Conference on Reverse Engineering (WCRE),‎ (DOI 10.1109/WCRE.2012.56)
  • [Marinescu, 2004] (en) Radu Marinescu, « Detection strategies: metrics-based rules for detecting design flaws », Software Maintenance, 2004. Proceedings. 20th IEEE International Conference on,‎ (DOI 10.1109/ICSM.2004.1357820)
  • [Moha et al., 2005] (en) Naouel Moha, Duc-loc Huynh et Yann-Gaël Guéhéneuc, « A Taxonomy and a First Study of Design Pattern Defects », 1st International Workshop on Design Pattern Theory and Practice, part of the STEP'05 workshop,‎ (DOI 10.1.1.182.3392)
  • [Moha et al., 2010] (en) Naouel Moha, Anne-Francoise Le Meur, Laurence Duchien et Yann-Gaël Guéhéneuc, « DECOR: A Method for the Specification and Detection of Code and Design Smells », Software Engineering, IEEE Transactions on (Volume:36 , Issue: 1 ),‎ (DOI 10.1109/TSE.2009.50)
  • [Rocco et al. 2010] (en) Rocco Oliveto, Foutse Khomh, Giuliano Antoniol et Yann-Gaël Guéhéneuc, « Numerical Signatures of Antipatterns: An Approach Based on B-Splines », Software Maintenance and Reengineering (CSMR), 2010 14th European Conference on,‎ (DOI 10.1109/CSMR.2010.47)