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

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
### Architectures Orientées Services

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. 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.

### Anti-patron

Les anti-patrons sont des erreurs courantes d'implémentation et de conception des logiciels. 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), 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.

## Spécification

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

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
* (CPL) couplage
* (COH) cohésion

### Métriques dynamiques

Les métriques dynamiques caractérisent l'exécution du service.
* (A) disponibilité
* (RT) temps de réponse

### Représentation BNF

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.
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 :

## Détection

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

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

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. 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.

### Résultats

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 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, SODA obtient une précision supérieure à 90% et un rappel de 100% lors de la détection.

## Exemples d'anti-patrons SOA$^,$

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

### DataService

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.

### TheKnot

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.

### ChattyService

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.

### NobodyHome

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.

### BottleneckService

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.

### SandPile

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.

### ServiceChain

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.