Détection d'anti-patrons de conception dans les architectures orientées services

Un article de Wikipédia, l'encyclopédie libre.

Les anti-patrons SOA sont des erreurs de conception issues de mauvais choix conceptuels récurrents dans les architectures orientées services (SOA). Les conséquences de ces défauts sont de freiner le développement et la maintenance des systèmes en rendant ceux-ci difficiles à évoluer et à maintenir. Une détection et une correction des anti-patrons implémentés dans un système sont importantes afin de faciliter les phrases de maintenance et d'évolution.

Anti-patron SOA[modifier | modifier le code]

Architectures Orientées Services[modifier | modifier le code]

Une architecture orientée services (notée SOA pour Services Oriented Architecture) est une architecture logicielle s'appuyant sur un ensemble de services simples. Les services web disposent de ce type d'architecture. L'objectif d'une architecture orientée services est donc de décomposer une fonctionnalité en un ensemble de fonctions basiques, appelées services, fournies par des composants et de décrire finement le schéma d'interaction entre ces services. Un service doit répondre à un besoin métier précis. Il doit être au maximum disponible sur le réseau et être autonome.

L'architecture SOA utilise différentes technologies de service distribué telles que REST, ou SOAP. L'ensemble des spécifications que doit adopter un SOA sont formalisées par le service component architecture (SCA) qui sont des standards proposés par le consortium OASIS[1]. Mais ces spécifications ne décrivent pas l'architecture de l'application, ni sa gestion pendant l'exécution, tel que le monitoring ou la reconfiguration[2].

Anti-patron[modifier | modifier le code]

Les anti-patrons sont des erreurs courantes d'implémentation et de conception des logiciels[3]. Comme les autres architectures, les web services évoluent dû aux exigences de l'utilisateur et du contexte, introduisant des anti-patrons dans le code. Les anti-patrons s'opposent à une conception utilisant des patrons de conception, désignés le plus souvent par le terme anglais design pattern.

Les effets dus aux anti-patrons dans les architectures orientées services sont une dégradation du design logiciel, de la qualité du service (QdS)[4], comme les problèmes de mise à l'échelle, performance et sécurité. Ils entraînent aussi une difficulté de maintenance et d'évolution pour l'application.

Dans les systèmes orientés objets, les patterns concernent les classes, alors que dans les architectures orientées services (SOA) les patterns concernent les services. Les SOA doivent donc avoir des patterns qui leur sont propres[5].

Spécification[modifier | modifier le code]

Une métrique logicielle est une mesure d'une propriété d'une partie d'un logiciel ou de ses spécifications.

Plusieurs mesures ont été créées pour permettre de spécifier chaque anti-patron, dont certaines transverses à plusieurs d'entre eux. Un langage spécifique (DSL) permet de définir des propriétés propres au domaine des SOA.

Métriques statiques[modifier | modifier le code]

Les propriétés statiques qui participent à la définition d'un anti-patron SOA, sont le design, la cohésion et le couplage. Voici une liste de propriétés à prendre en considération pour décrire un SOA, avec leur abréviation en anglais. Le premier élément « ALS » est une abréviation utilisée dans le modèle d'anti-patron utilisant la grammaire BNF et correspond par exemple à « Average Length Service » qui se traduit par « taille moyenne du service ».

  • (ALS) taille des signatures
  • (ARIP) ratio moyen de ports identiques
  • (ARIO) ration moyen des opérations identiques
  • (ARIM) ration moyen de messages identiques
  • (NCO) nombre d'opérations CRUD
  • (NOPT) nombre d'opérations dans un port type
  • (NPT) nombre de types de port
  • (NVMS) nombre de verbes dans les signatures d'un message
  • (NVOS) nombre de verbes dans les signatures d'une opération
  • (RGTS) ratio de termes dans les signatures
  • (ANP) nombre de paramètres d'une méthode"
  • (ANPT) nombre des différents types de paramètre
  • (NOD) nombre d'opérations
  • (ANIO) nombre moyen d'opérations identiques
  • (ANAO) nombre moyens d'accesseurs

Métriques dynamiques[modifier | modifier le code]

Les métriques dynamiques caractérisent l'exécution du service.

  • (A) disponibilité
  • (RT) temps de réponse

Représentation BNF[modifier | modifier le code]

La détection automatique d'anti-patrons a été expérimenté plusieurs fois. Une des approches, consiste à associer le code source d'une application vers un langage abstrait intermédiaire permettant d'être indépendant du langage d'implémentation d'un service web[6].

La spécification d'un anti-patron est un modèle hiérarchique de règles avec des propriétés plus ou moins élevées. Les propriétés d'utilisation et conception d'un SOA sont mesurées. Pour déterminer à quelle anti-patron peuvent correspondre ces mesures, un méta-langage permet de les mettre en relation. Il se base sur un ensemble de règles qui définissent quelles sont les mesures et valeurs cibles. Un ordre de grandeur permet de définir si une mesure sera faible ou forte, par exemple "RT = HIGH".

La grammaire BNF est le méta-langage utilisé pour la traduction d'anti-patrons dans la plupart des cas. L'exemple de grammaire BNF suivant décrit un anti-patron de manière générique :

rule card ::= RULE CARD:rule cardName { (rule)+ };
rule ::= RULE:ruleName { content rule };
content rule ::= operator rule rule | property | relationship
operator ::= INTER | UNION | DIFF | INCL | NEG
property ::= METRIC id metric metric value fuzziness | LEXIC id lexic ((lexic value)+) | STRUCT id struct
id metric ::= DIT | NINTERF | NMNOPARAM | LCOM | LOC METHOD | LOC CLASS | NAD | NMD | NACC | NPRIVFIELD | id metric + id metric | id metric - id metric
value metric ::= VERY HIGH | HIGH | MEDIUM | LOW | VERY LOW | NUMBER
id lexic ::= CLASS NAME | INTERFACE NAME | METHOD NAME | FIELD NAME | PARAMETER NAME
id struct ::= USE GLOBAL VARIABLE | NO POLYMORPHISM | IS DATACLASS | ABSTRACT CLASS | ACCESSOR METHOD | FUNCTION CLASS | FUNCTION METHOD | STATIC METHOD | PROTECTED METHOD | OVERRIDDEN METHOD | INHERITED METHOD | INHERITED VARIABLE
relationship ::= rel name FROM rule cardinality TO rule cardinality
rel name ::= ASSOC | AGGREG | COMPOS
cardinality ::= ONE | MANY | ONE OR MANY | OPTIONNALY ONE
rule cardName, ruleNam

Détection[modifier | modifier le code]

La résolution des anti-patrons permet d'améliorer la maintenance et l'évolution des SOA. Tout comme au niveau industriel, un logiciel peut être soumis à un contrôle de qualité via différents indicateurs. La qualité des SOA repose sur la détection de défauts d'architecture et de dynamicité.

Les attributs internes peuvent être mesurés très tôt dans le cycle de développement, et de façon régulière. Par prédiction aussi, des actions correctives peuvent être entreprises lors de l'implémentation, réduisant le coût de la maintenance dans le futur.

Les spécifications d'un anti-patron sont utilisées pour sa détection. Le code doit ainsi avoir une taille raisonnable et proportionnelle à la complexité des traitements. La complexité des algorithmes doit être minimisée.

Le temps de réponse et de disponibilité entrent en considération dans les spécifications de plusieurs anti-patrons, et sont cruciaux. Pour ces deux caractéristiques, la détection d'une mauvaise qualité de service s'effectue dynamiquement par invocation du SOA. Cette technique permet de s'affranchir des tâches de collecte et de filtrage des données d'introspection ou d'exécution interne.

Introspection de code[modifier | modifier le code]

Les défauts de design sont identifiables statiquement par introspection du code. Cette technique permet d'en déduire la structure de l'application. Les interfaces permettent d'avoir un modèle simple du service comprenant une grande partie des spécifications.

L'analyse des ports, opérations ou messages s'appuie sur la structure et la signification du code. La structure d'une application composée de plusieurs services, est évaluée par comparaison des mesures telles que les ports, opérations, messages à l'intérieur ou entre plusieurs services. Lors du traitement le code est considéré comme de simples chaînes de caractères. La comparaison se base sur une formule de distance entre deux éléments analysés, telle que la distance de Levenstein entre deux chaînes de caractères.

La signification des éléments doit également être prise en compte dans leur analyse, en plus de la comparaison syntaxique. Des mots différents utilisés dans le code peuvent avoir des significations identiques. Les outils lexicaux WordNet ou CoreNLP permettent d'évaluer la signification des structures en regroupant les noms, adjectifs ou les synonymes entre eux. C'est une analyse sémantique.

Une solution alternative a été développée dans le cadre de la détection de patrons de conception au cœur d'applications d'envergure. L'introspection repose cette fois sur des requêtes SQL, couplées à des expressions rationnelles.

Fouille des traces d'exécution[modifier | modifier le code]

Un mécanisme se base sur les traces d'exécution d'une application pour les objets suivants : association, héritage, classe abstraite, appel de méthode abstraite. Les traces d'exécution obtenues sont représentées sous forme de graphes et matrices qui sont comparées aux patrons de conception provenant du GoF (Gang of Four) préalablement modélisés avec ce même format de données[7]. L'algorithme de comparaison se base sur un score de similarité pour identifier les candidats qui varient par rapport aux patrons de conception architecturaux d'origine.

Une solution alternative se base sur un processus de détection dynamique de patrons de conception comportementaux. Un processus de rétro-ingénierie parcourt les traces d'exécution pour reconstruire un diagramme de scénarios sur l'application en cours d'analyse. Le principe consiste à comparer les diagrammes des patrons de conception d'origines avec les diagrammes extraits des traces d'exécution, en se basant une définition de similarité pour identifier les ressemblances[8].

Résultats[modifier | modifier le code]

Pour définir l'ordre de grandeur d'une mesure détectée, il faut d'abord conserver les valeurs les plus représentatives. La propriété aura une valeur qui peut s'obtenir avec la technique du boxplot appliquée aux résultats et traduite grâce à l'échelle de Likert. Le boxplot permet de comparer les valeurs des métriques pour différentes classes et ou systèmes, sans avoir à fixer de seuils artificiels. Il permet d’identifier également les valeurs extrêmes des métriques lorsque celles-ci sont en dehors des queues du boxplot. Cependant, le boxplot ne résout pas complètement le problème des seuils. Un degré de logique[9] permet de pallier ce problème en spécifiant une marge acceptable autour des seuils identifiés, ce qui permet d'inclure les valeurs proches de la valeur seuil.

Empiriquement la détection d'anti-patron est possible. SODA (Service Oriented Detection for Antipatterns) basée sur le framework SOFA, est un outil de détection actuellement viable. Testé sur un ensemble de services web au cours de travaux de recherche[10], SODA obtient une précision supérieure à 90% et un rappel de 100% lors de la détection.

Exemples d'anti-patrons SOA[11],[12][modifier | modifier le code]

Voici plusieurs exemples de spécifications d'antipatrons qui utilisent la grammaire BNF.

DataService[modifier | modifier le code]

DataService, alias Dataclass dans les systèmes orientés objets, correspond à un service qui contient principalement des accesseurs (Getteurs et Setteurs). Dans les applications distribuées, il peut y avoir certains services qui réalisent de simples récupérations ou accèdent à des données. Les DataServices contiennent habituellement des méthodes d’accès avec de petits paramètres de types primitifs. Ces services ont une forte cohésion des données.

RULE CARD: DataService {
     RULE: DataService {INTER HighDataAccessor SmallParameter PrimitiveParameter HighCohesion};
     RULE: SmallParameter {ANP LOW};
     RULE: PrimitiveParameter {ANPT HIGH};
     RULE: HighDataAccessor {ANAM VERY HIGH};
     RULE: HighCohesion {COH HIGH};
};

TheKnot[modifier | modifier le code]

TheKnot est un ensemble de services avec une faible cohésion qui sont fermement couplés. Ces services sont peu réutilisables. En raison d'une architecture complexe, leur temps de réponse est très grand et leur disponibilité faible.

RULE CARD: TheKnot {
     RULE: TheKnot {INTER HighCoupling LowCohesion LowAvailability HighResponse};
     RULE: HighCoupling {CPL VERY HIGH};
     RULE: LowCohesion {COH VERY LOW};
     RULE: LowAvailability {A LOW};
     RULE: HighResponse {RT HIGH};
};

ChattyService[modifier | modifier le code]

ChattyService correspond à plusieurs services qui échangent énormément de petites données de type primitif habituellement avec un anti-patron DataService. Il est aussi caractérisé par un nombre important d'invocations de méthode. Les anti-patrons ChattyService échangent énormément entre eux.

RULE CARD: ChattyService {
     RULE: ChattyService { INTER TotalInvocation DSRuleCard};
     RULE: DSRuleCard {RULE CARD: DataService};
     RULE: TotalInvocation {NMI VERY HIGH};
};

NobodyHome[modifier | modifier le code]

NobodyHome correspond à un service défini mais jamais utilisé par les clients. Les méthodes du service ne sont jamais invoquées même si elles sont couplées avec d'autres services. Pourtant il nécessite encore des déploiements ainsi que sa gestion malgré sa non-utilisation.

RULE CARD: NobodyHome {
     RULE: NobodyHome {INTER IncomingReference MethodInvocation};
     RULE: IncomingReference {NIR GREATER 0};
     RULE: MethodInvocation {NMI EQUAL 0};
};

BottleneckService[modifier | modifier le code]

BottleneckService est un service très utilisé par d'autres services ou clients. Il possède une forte cohésion entrante et sortante. Son temps de réponse peut être élevé parce qu'il peut être utilisé par de nombreux clients extérieurs, lesquels ont besoin d'attendre pour avoir accès a ce service. Cependant, sa disponibilité doit être faible à cause du trafic.

RULE CARD: BottleneckService {
     RULE: BottleneckService {INTER LowPerformance HighCoupling};
     RULE: LowPerformance {INTER LowAvailability HighResponse};
     RULE: HighResponse {RT HIGH};
     RULE: LowAvailability {A LOW};
     RULE: HighCoupling {CPL VERY HIGH};
};

SandPile[modifier | modifier le code]

SandPile est aussi connu sous le nom de "Fine-Grained Services". Il apparaît quand un service est composé de multiples petits services partageant une donnée commune, ce qui se traduit par une forte cohésion.

RULE CARD: SandPile {
     RULE: SandPile {COMPOS FROM ParentService ONE TO ChildService MANY};
     RULE: ChildService {ASSOC FROM ContainedService MANY TO DataSource ONE};
     RULE: ParentService {COH HIGH};
     RULE: DataSource {RULE CARD: DataService};
     RULE: ContainedService {NRO > 1};
};

ServiceChain[modifier | modifier le code]

ServiceChain alias MessageChain dans les systèmes orientés objet correspond à une chaîne de service. Le ServiceChain apparaît lorsque les clients demandent des invocations de services consécutifs pour atteindre leurs objectifs. Ce genre de chaînes de dépendances reflète l'invocation ultérieure de services.

RULE CARD: ServiceChain {
     RULE: ServiceChain {INTER TransitiveInvocation LowAvailability};
     RULE: TransitiveInvocation {NTMI VERY HIGH};
     RULE: LowAvailability {A LOW};
};

Articles connexes[modifier | modifier le code]

Notes et références[modifier | modifier le code]

  1. (en) « Specification SCA », sur OASIS Open Composite Services Architecture (Open CSA) Member Section advances open standards that simplify SOA.
  2. (en) Seinturier, L., Merle, P., Fournier, D., Dolet, N., Schiavoni, V. et Stefani, J.-B., « Reconfigurable SCA Applications with the FraSCAti Platform », Services Computing, 2009. SCC '09. IEEE International Conference on,‎ , p. 268 - 275
  3. (en) Koenig, « Patterns and Antipatterns », Journal of Object-Oriented Programming, no 8,‎
  4. (en) Naouel Moha, Francis Palma, Mathieu Nayrolles, Benjamin Joyen Conseil, Yann-Gaël Guéhéneuc, Benoit Baudry et Jean-Marc Jézéquel, « Specification and Detection of SOA Antipatterns », Lecture Notes in Computer Science « Service-Oriented Computing »,‎ , p. 1
  5. (en) « SOA Patterns – New Insights or Recycled Knowledge? », sur eaipatterns.com.
  6. (en) Giuliano Antoniol, Roberto Fiutem et Luca Cristoforetti, « Design pattern recovery in object-oriented software », IEEE,‎
  7. (en) Tsantalis, N., Chatzigeorgiou, A., Stephanides, G. et Halkidis, S.T., « Design Pattern Detection Using Similarity Scoring », Software Engineering, IEEE Transactions on, no Volume:32,‎ , p. 896 - 909
  8. (en) Poshyvanyk, D., Gueheneuc, Y.-G., Marcus, A., Antoniol, G. et Rajlich, V., « Back to Results Feature Location Using Probabilistic Ranking of Methods Based on Execution Scenarios and Information Retrieval », Software Engineering, IEEE Transactions on, no Volume: 33 , Issue: 6,‎ (ISSN 0098-5589, lire en ligne)
  9. (en) El Hachemi Alikacem et Houari Sahraoui, « Generic metric extraction framework », International Workshop on Software Measurement and Metrik Kongress(IWSM/MetriKon),‎ , p. 383–390
  10. (en) Mathieu Nayrolles, Francis Palma, Naouel Moha et Yann-Gaël Guéhéneuc, « Soda: A Tool Support for the Detection of SOA Antipatterns », Service-Oriented Computing,‎ , p. 451-455
  11. (en) Erl, « SOA Design Patterns », Prentice Hall PTR,‎
  12. (en) Rotem-Gal-Oz, « SOA Patterns », Manning Publications,‎