Vérification de conformité architecturale

Un article de Wikipédia, l'encyclopédie libre.
Sauter à la navigation Sauter à la recherche

La vérification de conformité architecturale (en anglais, architecture conformance checking) regroupe l'ensemble des vérifications statiques et dynamiques d'une implémentation d'un logiciel à partir de son architecture. Un humain peut détecter visuellement des violations en comparant deux modèles représentant une architecture. Ce procédé n'est pas sans faille puisqu'il peut nécessiter une grande concentration, une certaine difficulté et impliquer des erreurs en fonction de la complexité du modèle. Le modèle peut être constitué de multiples vues augmentant sa complexité. La vérification de conformité automatisée (entendre par là, une vérification informatique) est un choix préférable dans ce genre de cas.

Contexte[modifier | modifier le code]

Définition de l'érosion logicielle[modifier | modifier le code]

L'architecture logicielle est soumise constamment à des pressions sur les exigences et les technologies utilisées tout en continuant à délivrer un niveau de performance acceptable pour les utilisateurs finaux. L'érosion logicielle est l'écart entre l'architecture prévue et son implémentation finale qui change selon ces différentes pressions. Souvent, les modifications faites durant le développement d'un système provoquent des dommages sur l'intégralité de sa structure et violent ses principes de design[1].

Causes d'une érosion logicielle[modifier | modifier le code]

L'érosion peut survenir à cause de plusieurs facteurs incluant :

  • L'inconscience des développeurs logiciels puisqu'ils ne font pas toujours tous attention à respecter l'architecture établie au début du projet[2] ;
  • Les exigences contradictoires qui arrivent de façon imprévues au début du développement. Cela survient souvent quand la technologie choisie n'est pas maitrisée[2] ;
  • Les difficultés techniques qui peuvent survenir pendant l'implémentation lorsque les développeurs se rendent compte qu'un choix technologique ne parviendra pas à atteindre les objectifs désirés[2].
  • La pression des deadlines qui sont fréquentes dans le développement logiciel[2].

Résolutions[modifier | modifier le code]

Plusieurs stratégies existent pour tenter de contrôler l'érosion : la minimiser, la prévenir et la réparer[3]. La plus utilisée est la stratégie qui tente de minimiser l'érosion. Elle peut être implémentée par plusieurs techniques incluant la documentation, l'analyse et la surveillance de la conformité de l'architecture[3]. La stratégie pour prévenir l'érosion vise à complètement l'éradiquer[4]. Quant à la réparation, elle est utilisée pour déterminer si une implémentation est conforme à son architecture en réparant les dommages causés par l'érosion et réconciliant l'implémentation avec son architecture[4].

Pour chaque stratégie, il existe un second niveau de catégories classifiant plus précisément les différentes solutions[4] :

  • Minimiser
    • Processus orienté conformité de l'architecture inclut le processus d'ingénierie logicielle qui assure la conformité de l'architecture pendant le développement et la maintenance du système[4].
    • Gestion de l'évolution de l'architecture couvre les méthodes disponibles dans la gestion de l'évolution des spécifications logicielles en parallèle avec son implémentation[4].
    • Mise en application des principes architecturales qui incorpore des méthodes et des outils pour transformer des modèles architecturaux en implémentation[4].
  • Prévenir
    • Liaison de l'architecture vers son implémentation inclut les mécanismes qui associent les modèles architecturaux avec le code source et supporte la capacité de gérer la conformité architecturale à l'exécution[4].
    • Adaptation automatique des technologies permet aux systèmes de se reconfigurer eux-mêmes pour s'aligner avec leurs architectures après un changement sur leurs implémentations[5].
  • Réparer
    • Restauration de l'architecture implique d'extraire l'implémentation architecturale du code source[5].
    • Techniques pour découvrir les architectures sont utiles pour susciter l'architecture voulue à partir des propriétés du système[5].
    • Méthodes pour réconcilier l'écart entre l'implémentation et l'architecture voulue par le système[5].

Critères importants[modifier | modifier le code]

Vérification statique ou dynamique[modifier | modifier le code]

Les vérifications statiques sont effectuées sans exécuter le code. Elles sont faites pendant la compilation d'un système ou pendant sa phase de maintenance où l'application n'est plus connectée à son environnement de production. Elles peuvent être liées à la structure du code et les aspects de l'intégrité de la communication[6].

Il existe trois approches principales pour les vérifications statiques[7] :

  • La réflexion par modèles : Cette approche compare deux modèles du logiciel entre eux. Typiquement, entre une architecture visée du logiciel et une architecture basée sur le code source. La comparaison requiert un mapping entre les deux modèles pour effectuer la comparaison. Le mapping doit se faire manuellement par un développeur[7].
  • Les règles de conformité entre les éléments de l'architecture : Les règles permettent d'autoriser ou d'interdire les relations entre deux composants de l'architecture. Elles peuvent mettre en évidence les violations comme la réflexion par modèles mais par contre le mapping est fait automatiquement[7].
  • Les règles d'accès des composants : L'approche met en place de simples ports pour chaque composants et spécifie les composants qui sont autorisés à y accéder[7].

Les vérifications dynamiques ont deux objectifs : vérifier l'exécution et la cohérence entre l'architecture du système et la spécification définie[8]. Elles sont utilisées comme une protection contre les fautes potentielles à l'exécution. Cette protection est implémentée par un moniteur pour pouvoir réagir aux différentes violations[9]. Les vérifications dynamiques sont effectuées pendant que le système s'exécute et nécessitent donc l'accès à l'état d'exécution des opérations. Ces opérations sont validées par des contraintes architecturales dépendantes d'une solution souvent externe[6].

Ces deux types de vérifications peuvent être utilisés de façon complémentaire pour de la vérification de conformité entre une architecture et son implémentation[10].

Rapprochement entre l’architecture et son implémentation[modifier | modifier le code]

Les vérifications de conformité se base sur un mapping entre l'architecture et son implémentation. Ce rapprochement est nécessaire pour lancer les vérifications. Il en existe différentes catégories qui sont toutes utilisées par différentes solutions[11] :

  • Les conventions de nommage à partir de l'architecture sur l'implémentation du programme. Cette technique peut être étendue par des annotations pour enrichir l'information sur l'architecture en faisant correspondre l'information avec l'implémentation correspondante[11].
  • Combiner l'architecture et son implémentation dans une seule spécification. L'architecture fait partie intégrante de l'implémentation. Elle est développée dans l'application cible. Cependant, cette approche demande une plateforme d'exécution permanente[11].
  • Spécifier les informations de mapping dans une spécification externe (à la fois de l'architecture et son implémentation). Elle demande un projet séparé pour avoir un mapping explicite pour toutes les fonctionnalités architecturales[11].

Principales approches / Solutions existantes[modifier | modifier le code]

PandArch[modifier | modifier le code]

Principe[modifier | modifier le code]

PandArch est un framework de vérifications de conformité entre l'architecture et l'implémentation d'un logiciel. Cette solution est designée pour être connectable, automatisée, personnalisable, non intrusive et extensible. Grâce à ces principes, elle vise à limiter les problèmes connus de vérifications en limitant l'impact sur les performances du logiciel cible, quand les vérifications sont actives. L'objectif principal de ce framework est de rendre la vérification de conformité dynamique d'architectures une option viable pour les développeurs[6].

La réalisation de PandArch a été motivée par plusieurs principes importants :

  • Connectable : L'application cible peut s'exécuter avec ou sans le framework. Quand la solution n'est pas attachée à l'application, les fichiers compilés ne sont pas manipulés[11],
  • Automatisée : La génération des règles de conformité et leurs vérifications sont automatisées[11],
  • Non intrusive : Le code source de l'application cible reste inchangé[11],
  • Les métriques sur la performance : L'impact sur les performances de l'application cible est minimalisé le plus possible[11],
  • Extensible : Le framework peut s'accommoder des modifications sur les règles de conformité[11].

Objectifs[modifier | modifier le code]

Vérifier la conformité des fonctionnalités dynamiques par rapport à une implémentation n'est pas toujours possible quand le système est déployé dans son environnement de production. De plus, les routines de maintenance modifient les pré-requis et les opérations peuvent alors causer une déviation du comportement de l'application en production[12].

PandArch vient proposer une solution pour la détection de violations à l'exécution d'un programme avec ses motivations sur la minimalisation des impacts sur l'application cible. La conformité des fonctionnalités dynamiques inclut l'instanciation à l'exécution, l'invocation de méthodes réflectives, les liaisons dynamiques, la qualité des services, etc[12].

Fonctionnement[modifier | modifier le code]

La vérification de conformité entre l'architecture et l'implémentation d'un logiciel nécessite l'utilisation d'un système de surveillance pour reconstruire une vue de l'architecture à l'exécution de l'application cible. L'architecture extraite est utilisée pour les vérifications de conformité[12].

L'exécution du mécanisme de vérification architecturale de conformité se base sur une spécification de l'architecture. Cette spécification contient les annotations de mapping entre l'architecture et l'implémentation du logiciel cible. Les contraintes architecturales et les informations sur ce mapping sont extraites à partir de la compilation de cette spécification, et elles sont utilisées par le générateur de règles pour créer l'ensemble des règles de conformité[11].

Parallèlement à cela, le vérificateur de conformité prendra l'ensemble des règles de conformité. Il les validera pendant les évènements d'exécution survenant à l'exécution du programme. Ce processus peut alors produire une série de violations pour notifier l'architecte des dérivations présentes dans l'implémentation à partir de l'architecture[13].

Card[modifier | modifier le code]

Principe[modifier | modifier le code]

Card (de l'anglais Controlling Architectural Degradation) est un outil pour identifier l'érosion de l'architecture d'un programme Java. Cette solution a été développée pour être automatisée et accessible. Elle n'a pas besoin de spécifications, de descriptions architecturales et elle peut se suffire à elle-même, aucune dépendance n'est nécessaire. Elle utilise un langage de modélisation répandue et couramment utilisé par les développeurs, l'UML 2.0[14].

Il existe quelques fonctionnalités importantes dans Card :

  • Un ensemble de règles définissant la conformité entre les diagrammes de classes et les diagrammes de séquences de l'UML 2.0 et l'implémentation Java[14].
  • Le concept d'une spécification maitre, qui peut être soit le modèle soit l'implémentation[14].
  • Une extension Eclipse qui implémente la vérification de conformité comme définit dans les règles de l'architecte[14].

Objectifs[modifier | modifier le code]

L'érosion architecturale est un problème bien connu et il existe déjà plusieurs approches pour prévenir, minimiser ou réparer ces érosions, principalement basé sur la concept de conformité. Cependant, la plupart de ces approches demande une rigueur stricte sur la spécification de l'architecture du logiciel cible avec l'utilisation d'un ou plusieurs outils. Des interventions manuelles sont aussi nécessaire pour le processus de vérification qui limite sa potentielle utilisation en milieu d'entreprise[14].

Les objectifs de Card tentent de résoudre tous ces problèmes en proposant un outil pour identifier l'érosion architecturale d'un programme comme solution envisageable par les entreprises[14].

Fonctionnement[modifier | modifier le code]

Son fonctionnement se base sur l'utilisation de deux catégories de règles de conformité : des règles structurelles et d'interaction. La première catégorie concerne la structure statique d'une architecture, comme de l'héritage entre deux éléments. La seconde catégorie concerne l'interaction entre les éléments comme l'ordre des méthodes d'invocation ou la communication des éléments. Les règles structurelles sont déduites à partir du diagramme de classes de l'architecture de l'application cible alors que les règles d'interaction sont dérivés à partir du diagramme de classes et du diagramme de séquences[10].

ArchJava[modifier | modifier le code]

Principe[modifier | modifier le code]

ArchJava est une extension du langage Java qui permet de mêler la spécification de l'architecture d'un logiciel avec son implémentation. L'architecture est décrite dans le même langage que son implémentation ce qui permet d'exprimer efficacement les contraintes architecturales[15].

Objectifs[modifier | modifier le code]

Cette approche qui allie architecture et implémentation a pour principaux objectifs :

  • Une meilleure compréhension de l'application[16],
  • Une architecture fiable couplée avec son implémentation[16],
  • Une cohérence assurée entre l'architecture et son implémentation durant leur évolution[16],
  • Les développeurs encouragés à suivre une implémentation orientée architecture[16].

Fonctionnement[modifier | modifier le code]

Pour permettre aux développeurs de décrire l'architecture du logiciel, ArchJava ajoute au langage Java de nouveaux éléments dédiés à la description de l'architecture[16]. Les éléments ajoutés sont :

  • Les composants (components) qui sont un type spécial d'objet Java et communiquent entre eux de façon structuré[17],
  • Les ports représentent un channel de communication entre un composant et un ou plusieurs autres composants[17],
  • Les connexions (connect) qui relient deux ou plusieurs ports ensembles[17].

Avec ces éléments, le développeur spécifie le comportement de la fonctionnalité sur laquelle il travaille. Les échanges et dépendances sont spécifiés en fonction des contraintes architecturales au sein même du code[17].

SAVE[modifier | modifier le code]

Principe[modifier | modifier le code]

SAVE (Software Architecture Visualization and Evaluation) est un outil qui permet d'extraire l'architecture d'un logiciel à partir de son code source pour ensuite la comparer à l'architecture visée initialement[18].

Objectifs[modifier | modifier le code]

SAVE a pour objectif d'aider le développeur en lui fournissant une vision de l'architecture basée sur l'implémentation pour lui exposer les violations des contraintes architecturales. L'outil permet aussi de mettre en évidence les parties de l'application qui ont besoin de plus d'attention de la part du développeur. Elles peuvent réduire de manière significative le nombre de violations architecturales[18].

Fonctionnement[modifier | modifier le code]

Le processus pour appliquer SAVE est constitué de six étapes [18]:

  1. Capturer et modéliser l'architecture visée[18].
  2. Extraire l'architecture basée sur l'implémentation pour abstraire la structure du code et de ses dépendances[18].
  3. Faire le mapping entre l'architecture visée et l'architecture d'implémentation. Le mapping est effectué manuellement par les architectes et les développeurs chargés du design[18].
  4. Faire la comparaison entre l'architecture visée et l'architecture d'implémentation en fonction du mapping effectué à l'étape précédente. SAVE signale chaque élément de l'architecture d'implémentation qui ne correspond pas à l'architecture visée[18].
  5. Analyser chaque violation pour déterminer si elle est critique ou non. Cette étape est aussi manuelle mais facilitée par la capacité de l'outil à parcourir le code source[18].
  6. Etablir un plan pour retirer les violations considérées critiques. La complexité de cette étape dépend du nombre de violations signalées. Un petit nombre de violations est facile à retirer d'un système, tandis qu'un grand nombre de violations peut conduire à un refactoring du code source[18].

Vérification via des séquences à l'exécution[modifier | modifier le code]

Cette solution propose une méthode semi-automatique et dynamique de vérification de conformité[19].

Principe[modifier | modifier le code]

L'approche principale de cette méthode est de pouvoir vérifier la conformité d'un système en retraçant son exécution par rapport à la description de son implémentation. La méthode est basée sur la combinaison de deux techniques. La première est une technique quant au respect d'une implémentation par rapport aux règles initiales de son architecture. Elle fait le lien entre une architecture et son implémentation pour en ressortir les violations. La seconde repose sur le principe d'injection, les règles architecturales sont insérées dans la technologie d'implémentation permettant une approche de développement plus orientée selon son architecture[19].

Objectifs[modifier | modifier le code]

L'objectif final de ce procédé est d'aider l'ingénieur logiciel à s'assurer de la fiabilité du système implémenté. D'abord en démontrant que l'architecture de son implémentation a bien les propriétés désirées puis en maintenant la correspondance vis-à-vis de son architecture initiale[20].

Fonctionnement[modifier | modifier le code]

La méthode est constituée de deux étapes[21] :

  • La première consiste en l'extraction des données à l'exécution du système, pour en ressortir une séquence de messages représentant l'exécution du système sous forme de chaîne de caractères[22].
  • La seconde applique un filtre sur la séquence extraite qui contient des messages non pertinents. Afin de réduire la trace d'exécution, un filtre est appliqué pour obtenir une trace plus pertinente par rapport à celle prescrite par l'architecture. Les séquences extraites consistent en des messages enregistrés lors de l'exécution d'un cas d'utilisation du système[22].

La séquence prescriptive est établie par rapport aux spécificités de l'architecture initiale. Par exemple, si le message A apparait avant le message B alors il est prescrit que le message A doit avoir eu lieu avant le message B[22].

Cette méthode est donc dynamique car elle manipule des données à l'exécution du système. Elle est aussi semi-automatique car, finalement, c'est l'ingénieur même qui juge si la séquence extraite est conforme ou non à la séquence prescriptive. En effet, même si visualiser les différences entre les deux séquences peuvent être facilitées par un outil, seul un ingénieur peut décider s'il y a une violation par rapport à l'architecture initiale[21].

Évaluations des solutions existantes[modifier | modifier le code]

Avantages et inconvénients des solutions existantes
Solutions Avantages Inconvénients
PandArch
  • PandArch est designé pour être connectable, automatisé, personnalisable, non intrusif et extensible[11].
  • Capacité à détecter les violations de conformité basé sur les règles de conformité et les évènements d'exécution[23].
  • Faible impact sur les performances de l'application cible[23].
  • La génération automatique des règles de conformité n'affecte pas le code source de l'application cible[24].
  • Des tests supplémentaires sur des projets de types différents sont nécessaires pour déterminer la viabilité et l'efficacité du framework[25].
  • L'implémentation actuelle ne prend pas en charge les applications distribuées ou la vérification statique de conformité[25].
Card
  • Card est designé pour être extensible et flexible[26].
  • Vérifie que toutes les violations possibles sont trouvées dans tous les cas, violations définies par les règles de conformité[27].
  • Utilisation conviviale, flexible et offre des options adaptées pour les développeurs logiciels avec l'environnement Eclipse[27].
  • Met un point d'honneur sur la performance de l'exécution de Card sur un projet[27].
  • Les performances sur la vérification de conformité peuvent être améliorées en fournissant un lien entre l'architecture et son implémentation[28].
  • L'extension Eclipse ne suggère pas de correction pour toutes les violations trouvées[28].
ArchJava
  • Transcrit facilement en ArchJava l'architecture conceptuelle d'un projet de taille modérée (d'au moins 10.000 lignes de code)[29].
  • Le langage rend l'architecture explicite en exprimant les communications entre protocoles à travers des ports. Ce qui aide à nettoyer les communications non voulues au sein du programme[15].
  • N'est pas au optimisé pour être appliqué sur des projets de grande taille (d'au moins 100.000 lignes de code)[29].
SAVE
  • Identifie facilement les violations architecturales en utilisant la réflexion par modèles[30].
  • Supprime les connexions non désirées, entre l'architecture visée et l'architecture basée sur le code source, tout en gardant les fonctionnalités voulues intactes[30].
  • Analyse statique qui ne détecte pas les structures dynamiques qui sont d'avantages liées à l'architecture conceptuelle[30].
  • L'évaluation peut entraîner un refactoring important après la fin du développement du logiciel[31].
Vérification via des séquences à l'exécution
  • L'approche se concentre uniquement sur la communication architecturale ce qui réduit la trace obtenue à l'exécution[20].
  • L'analyse peut s'effectuer sur un cas d'utilisation précis de l'application[20].
  • L'approche se base sur les architectures orientées évènements mais peut être appliquée sur d'autres systèmes à condition qu'un mapping existe entre l'implémentation du système et son architecture[20].
  • L'analyse est optimisée pour les architectures orientées évènements et non pour d'autres frameworks et technologies[20].

Références[modifier | modifier le code]

  1. De Silva 2012, p. 132
  2. a b c et d De Dimech 2013, p. 208
  3. a et b De Dimech 2013, p. 211
  4. a b c d e f et g De Silva 2012, p. 134
  5. a b c et d De Silva 2012, p. 135
  6. a b et c De Silva 2013, p. 241
  7. a b c et d Knodel 2007, p. 2
  8. Yang 2011, p. 2
  9. Yang 2011, p. 1
  10. a et b De Dimech 2013, p. 212
  11. a b c d e f g h i j et k De Silva 2013, p. 242
  12. a b et c De Silva 2013, p. 240
  13. De Silva 2013, p. 243
  14. a b c d e et f De Dimech 2013, p. 209
  15. a et b Aldrich 2002, p. 187
  16. a b c d et e Aldrich 2002, p. 188
  17. a b c et d Aldrich 2002, p. 189
  18. a b c d e f g h et i Lindvall 2008, p. 99
  19. a et b Medvidovic 2013, p. 1
  20. a b c d et e Medvidovic 2013, p. 6
  21. a et b Medvidovic 2013, p. 2
  22. a b et c Medvidovic 2013, p. 3
  23. a et b De Silva 2013, p. 245
  24. De Silva 2013, p. 246
  25. a et b De Silva 2013, p. 247
  26. De Dimech 2013, p. 218
  27. a b et c De Dimech 2013, p. 219
  28. a et b De Dimech 2013, p. 222
  29. a et b Aldrich 2002, p. 197
  30. a b et c Lindvall 2008, p. 100
  31. Lindvall 2008, p. 101

Bibliographie[modifier | modifier le code]

  • (en) Lakshitha De Silva et Dharini Balasubramaniam, « PANDArch: A Pluggable Automated Non-intrusive Dynamic Architecture Conformance Checker », Software Architecture, Springer Berlin Heidelberg,‎ , p. 240-248 (ISBN 978-3-642-39030-2 et 978-3-642-39031-9, DOI 10.1007/978-3-642-39031-9_21)
  • (en) Claire Dimech et Dharini Balasubramaniam, « Maintaining Architectural Conformance during Software Development: A Practical Approach », Software Architecture, Springer Berlin Heidelberg,‎ , p. 208-223 (ISBN 978-3-642-39030-2 et 978-3-642-39031-9, DOI 10.1007/978-3-642-39031-9_19)
  • (en) Lakshitha de Silva et Dharini Balasubramaniam, « Controlling software architecture erosion: A survey », Journal of Systems and Software, vol. 85, no 1,‎ , p. 132-151 (ISSN 0164-1212, DOI 10.1016/j.jss.2011.07.036, lire en ligne)
  • (en) Hongwei Yang, « A Runtime Model Checker for Dynamic Software Based on Aspect-Oriented Programming », Intelligent Systems and Applications (ISA), 2011 3rd International Workshop,‎ 2011, p. 1-3 (DOI 10.1109/ISA.2011.5873401)
  • (en) Nenad Medvidovic et Daniel Popescu, « Ensuring Architectural Conformance in Message-Based Systems », IEEE Concurrency,‎ 2008
  • (en) Peyman Oreizy, Nenad Medvidovic et Richard N. Taylor, « Runtime software adaptation: framework, approaches, and styles », ICSE Companion '08 Companion of the 30th international, New York, NY, USA,‎ , p. 899–910 (ISBN 978-1-60558-079-1, DOI 10.1145/1370175.1370181, lire en ligne)
  • (en) Jonathan Aldrich, Craig Chambers et David Notkin, « ArchJava: Connecting Software Architecture to Implementation », ICSE '02 Proceedings of the 24th International Conference, New York, NY, USA,‎ 2002, p. 187–197 (ISBN 1-58113-472-X, DOI 10.1145/581339.581365, lire en ligne)
  • (en) M. Lindvall et Dirk Muthig, « Bridging the Software Architecture Gap », Computer, vol. 41, no 6,‎ 2008, p. 98-101 (ISSN 0018-9162, DOI 10.1109/MC.2008.176)
  • (en) Jens Knodel et Daniel Popescu, « A Comparison of Static Architecture Compliance Checking Approaches », Software Architecture, 2007. WICSA '07. The Working IEEE/IFIP Conference,‎ 2007, p. 12-12 (DOI 10.1109/WICSA.2007.1)