Dégradation logicielle
La dégradation logicielle, nommée également érosion logicielle, est le déséquilibre entre l'architecture logicielle et son implémentation. Le terme «vieillissement logiciel» est également utilisé pour faire allusion aux défaillances rencontrées dans un logiciel au fil du temps[1]. Il semble impossible d'empêcher ledit vieillissement, mais il existe des moyens pour le ralentir, d'où l'intérêt de différentes architectures logicielles.
L'architecture logicielle permet de décrire comment doit être conçu le logiciel pour répondre aux spécifications de celui-ci. L'implémentation logicielle doit correspondre au modèle d'architecture produit lors de la phase de conception. Dans la pratique, il n'est pas toujours évident de respecter cette règle. Les origines des décalages sont multiples : l'évolution logicielle, les erreurs d'implémentations, les contradictions dans l'architecture envisagée qui ne pouvaient être prévues avant le développement, etc. Il est possible de faire face à cette problématique en appliquant des concepts du génie logiciel.
Principe de base
modifier![](http://upload.wikimedia.org/wikipedia/commons/thumb/b/b3/Schema_cycle_de_developpement.png/279px-Schema_cycle_de_developpement.png)
Pour comprendre l'importance de l'architecture, il est nécessaire de connaître les différentes étapes à suivre lors de la réalisation d'un projet. Tout projet est issu d'un besoin. Pour satisfaire les futurs utilisateurs, il est nécessaire d'étudier leurs besoins avant de développer une solution. Grâce à cela, il sera possible de définir une architecture logicielle adaptée afin d'obtenir un résultat proche de celui escompté. Avec une architecture bien définie, l'implémentation de la solution sera facilitée et correspondra mieux aux attentes du client s'il n'y a pas de divergences entre les deux.
L'importance de l'architecture logicielle
modifierL'architecture logicielle permet de réaliser entièrement le logiciel sous une forme théorique avant de le réaliser de manière pratique. Ceci permet de prévoir les contraintes techniques, d'envisager les évolutions de manière adaptée et de garantir la qualité du logiciel. Par conséquent, les coûts sont réduits et les logiciels sont sensiblement de meilleures qualités. L'architecture logicielle joue un rôle important dans les six aspects[2], ci-dessous, du développement logiciel :
- Elle simplifie notre capacité à comprendre les gros systèmes en les représentant par un niveau d'abstraction dans lequel une architecture de système haut niveau peut facilement être perçue.
- Elle favorise la réutilisation à multiples niveaux, des bibliothèques de composants aux framework.
- Elle permet la construction d'un plan pour le développement en indiquant les dépendances entre les différents composants.
- Elle facilite la mise en place des évolutions.
- Elle offre des nouvelles possibilités pour l'analyse telles que la vérification de la cohérence du système, la conformité des contraintes imposées par le style d'architecture, etc.
- Elle permet la bonne gestion de projets.
Liaisons entre architectures et implémentations
modifierPour faire la liaison entre l'architecture et l'implémentation, il est nécessaire de définir un ensemble de règles. Celles-ci permettront de détecter lorsque l'implémentation sera en train de dévier de l'architecture.
Il est possible de distinguer deux types de règles: les règles structurelles[3] et les règles d’interactions[4]. Les règles structurelles concernent l'existence des mêmes entités et les relations qui les unissent tandis que les règles d’interactions concernent essentiellement la présence des appels de méthode dans le même ordre.
Avec cet ensemble de règles[5], lors de l'analyse il y a trois types de résultats possibles :
- Convergence : La relation implémentée correspond à celle définie dans l'architecture.
- Divergence : La relation implémentée diffère de celle définie dans l'architecture.
- Absence : La relation est présente dans l'architecture mais n'est pas implémentée.
Il suffit maintenant de traiter chaque divergence et absence une par une. La pratique la plus courante est de modifier le code pour qu'il corresponde à l'architecture. Néanmoins, il est possible de devoir modifier l'architecture du projet à cause de difficultés techniques lors du développement.
Causes de dégradations logicielles
modifierLes principales causes[1] des dégradations logicielles sont les modifications apportées au code, à la documentation dans le non-respect des règles architecturales. Ces changements sont nécessaires pour suivantes raisons.
Changement des besoins utilisateurs
modifierL'une des principales causes des dégradations dans les architectures est l'évolution du besoin client. Le client n'est pas toujours conscient de ce qu'il attend jusqu'à ce qu'il ait une première version du produit. Il essaye alors d'apporter des modifications aux spécifications. Ce problème est également constaté lorsque les spécifications ne sont pas assez précises. Ces deux points définissent les deux principaux types de vieillissement logiciels : les défaillances causées par les modifications des propriétaires du produit à la suite des évolutions du besoin, et le résultat des modifications effectuées à la suite d'incompréhensions des deux parties (client/concepteur du logiciel) lors de la conception et du développement du produit.
Évolution du matériel
modifierUne autre cause de dégradations de logicielles est le matériel auquel se rattache le logiciel. Les architectures logicielles sont conçues dans le respect du matériel dont le logiciel dépend. Au fil du temps, le matériel est susceptible de changer[6] et cela peut provoquer une instabilité et compromettre l'architecture prévue.
Allocation mémoire
modifierLes modifications apportées au logiciel durant sa durée de vie entraînent un problème d'allocation mémoire[6]. En effet, plus il y a des changements dans le code, plus la taille du programme grandit, et plus la taille du programme grandit plus la mémoire demandée au système est conséquente. Il est difficile de prédéfinir la mémoire à allouer.
Idées de solutions
modifierPour faire face aux dégradations logicielles, il existe plusieurs solutions permettant de ralentir le vieillissement[7] mais également de garantir la qualité tout en essayant de garder un équilibre entre l'architecture et l'implémentation. Certaines technologies (citées plus bas) permettent de faire face aux dégradations. Cependant il existe des éléments pratiques à mettre en place pour conserver la qualité des logiciels.
Mise en place d'architectures adaptées
modifierLe but de la phase de conception est de créer un design capable d'accepter des demandes de changements futurs.
Ceci est en contradiction avec l'itérative nature de nombreuses méthodes de développement (extrême pro- programming, le prototypage rapide, etc.) car ces méthodologies incorporent généralement de nouvelles exigences qui peuvent avoir un impact architectural, au cours du développement alors qu'une bonne conception nécessite des connaissances au sujet de ces exigences à l'avance[8].
Il reste donc important de prévoir des architectures s'adaptant aux changements mais également compatibles avec les méthodologies de développement utilisées. Ainsi, il semble possible de parler d'architectures agiles[9] pour des développements agiles et l'appliquer pour mieux garantir la durée de vie du logiciel.
Équilibre entre architecture, code, documentation lors des évolutions
modifierLorsqu'il y a des modifications à apporter au logiciel, il semble plus simple (moins cher) d'appliquer ces modifications dans le code. Pour pouvoir retarder le vieillissement, il est primordial de maintenir l'architecture et la documentation. En effet, il faut garantir à chaque changement dans le code que les règles d'architectures sont respectées et la documentation mise à jour. Ceci permet d'éviter les décalages pouvant subvenir entre l'implémentation et l'architecture logicielle.
Maintenance
modifierUne bonne maintenance logicielle permet d'allonger la durée de vie du logiciel. Les processus de maintenances se basent généralement sur l'amélioration itérative ou encore sur le modèle de réutilisation complète[10]. La réutilisation permet de gagner du temps, réduire le coût mais peut s'avérer dangereux. Il est donc important de :
- Identifier les différents composants logiciels
- Analyser les composants (par rapport aux besoins du logiciel)
- Adapter les composants au contexte
- Effectuer l'intégration
Il est important lors de la maintenance, de respecter les règles architecturales, surtout, lors de l'intégration de nouveaux composants.
Bonnes pratiques
modifierIl existe des éléments pratiques, ci-dessous, permettant de garantir un équilibre entre l'architecture logicielle et son implémentation.
- Ne pas attendre la fin du développement avant d'effectuer des analyses de divergences entre l'architecture et le code car le refactoring sera plus complexe[11].
- Lors de la conception, prévoir une architecture décrivant le logiciel répondant aux besoins clients tout en laissant les possibilités de l'étendre; et lors de l'implémentation garder également ses possibilités tout en respectant les règles imposées par l'architecture.
- Maintenir la cohérence entre le code et la documentation.
- Trouver le bon compromis entre les stratégies d'efforts[12]: minimal et optimal.
- S'efforcer de modulariser.
- Élaborer des architectures claires et expressives.
- Prévoir des architectures correspondantes aux méthodologies utilisées.
- Réutiliser ce qui est réutilisable, si et seulement si cela répond aux besoins.
- Utiliser le concept PDCA[13](Plan, Do, Check, Act).
Technologies
modifierCard
modifierCard[14] a été développé par Claire Dimech et Dharini Balasubramaniam de l'École d'informatique de l'Université de St Andrews.
Card est un outil de vérification de conformité entre architecture et implémentation, il est intégré sous forme de plugin dans Eclipse. La vérification se fait statiquement entre une description d'architecture en UML et son implémentation en Java. Ce framework contient deux modules de prétraitement : l'un pour les diagrammes UML 2.0 et l'autre pour le code source Java. Card se charge de rechercher les fichiers UML et Java dans l'arborescence du projet Eclipse, ensuite utilise ses préprocesseurs pour l'extraction des propriétés architecturales. Ces propriétés sont stockées dans des structures de données adaptées pour l'analyse de conformité à effectuer.
Card se base sur le concept "Maître Esclave", architecture prescriptive (Maître) et architecture descriptive (Esclave), sur lesquelles se réfèrent les règles. Card permet un paramétrage par utilisateur sur trois niveaux d'exigences (High, Medium, Low), procède à une vérification des structures de données et affiche les violations en les renvoyant vers l'esclave. Les développeurs peuvent vérifier la conformité entre leur code et le model en mode static (offline) ou dynamiquement (ils peuvent le choisir dans les préférences).
Card a été testé sur de nombreux projets et n'a jamais fait ressortir de fausses violations ni d'oublis. Cependant, il n'y a pas de preuves formelles.
SAVE
modifierSAVE[15] a été développé conjointement par Fraunhofer IESE (Institute for Experimental Software Engineering, Institut de recherche en ingénierie logicielle en Français) à Kaiserslautern en Allemagne et Fraunhofer Center Maryland (Center for Experimental Software Engineering, Centre de recherche en ingénierie logicielle en Français) à Maryland aux États-Unis.
SAVE est un outil de développement qui montre les convergences et divergences entre deux entités d'un projet de manière schématique. Cet outil est disponible sous la forme de plugin Eclipse et est donc complètement intégré à celui-ci. Il est utilisable sur les projets développés en Java, C/C++, et Delphi.
La version statique a été testé dans l'entreprise TESTO pendant une période de trois ans pour développer une douzaine de produits, et l'étude présente des résultats concluants[16].
Il existe également un plugin (LiFe)[7] permettant d'effectuer la vérification au fur et à mesure que le code de l'application est écrit. Ce plugin a également été testé sur une promo d'étudiants où certains groupes avaient le plugin SAVE Life et le reste ne disposaient d'aucun outil de vérification. L'étude montre qu'après quelques semaines, les groupes d'étudiants qui développaient avec le plugin faisaient beaucoup moins d'erreurs d'implémentations. Finalement, le projet était plus proche du résultat attendu que celui des autres groupes.
ArchJava
modifierArchJava[17] est l'une des premières solutions développés afin de contrôler la cohésion entre l'architecture et l'implémentation. Cette solution a vu le jour en 2002 aux États-Unis.
ArchJava est un langage étendu de Java permettant la mise en place de contraintes architecturales lors de l'implémentation. Ces contraintes sont spécifiées explicitement dans le code en ajoutant des entités nommées port[18] dans les classes. Ces ports permettent de définir quels objets peuvent communiquer entre eux et quelles sont les méthodes autorisées sur ce port.
Une étude[19] a été menée pour vérifier les points suivants :
- Peut-on définir l'architecture d'un projet à grande échelle avec ArchJava ?
- Quel est le coup d'un refactoring d'un projet Java vers ArchJava ?
- ArchJava permet-il l'évolution logicielle ?
L'ensemble des points ont été vérifiés avec succès, et la compréhension du code du projet testé a été fortement améliorée car les communications ont été simplifiées.
Références
modifier- Lorge Parnas, p. 279
- Garlan, p. 94.
- Dimech, p. 212.
- Dimech, p. 213.
- Jens, p. 43.
- Lorge Parnas, p. 281.
- Constructive architecture compliance checking — an experiment on support by live feedback
- Gurp, p. 106.
- Kruchten.
- Baldassarre.
- A framework for the validation of processor architecture compliance
- Gurp, p. 117.
- Jens, p. 289.
- Maintaining Architectural Conformance during Software Development: A Practical Approach
- SAVE: Software Architecture Visualization and Evaluation
- Architecture Compliance Checking - Experiences from Successful Technology Transfer to Industry
- ArchJava: connecting software architecture to implementation
- Aldrich, p. 189.
- Aldrich, p. 192.
Bibliographie
modifier- (en) Philippe Kruchten, « Software architecture and agile software development: a clash of two cultures? », Software Engineering, 2010 ACM/IEEE 32nd International Conference on (Volume:2 ), , p. 497 - 498 (ISSN 0270-5257, DOI 10.1145/1810295.1810448)
- (en) David Garlan et Carnegie Mellon, « Software architecture: a roadmap », Proceedings of the Conference on The Future of Software Engineering, , p. 91 - 101 (ISBN 1-58113-253-0, DOI 10.1145/336512.336537)
- (en) Duszynski S., Knodel Jens et Lindvall M., « SAVE: Software Architecture Visualization and Evaluation », Software Maintenance and Reengineering, 2009. CSMR '09. 13th European Conference, , p. 323 - 324 (ISBN 978-0-7695-3589-0, ISSN 1534-5351, DOI 10.1109/CSMR.2009.52)
- (en) Knodel Jens, Muthig Dirk et Rost D., « Constructive architecture compliance checking — an experiment on support by live feedback », Software Maintenance, 2008. ICSM 2008. IEEE International Conference, , p. 287 - 296 (ISBN 978-1-4244-2614-0, ISSN 1063-6773, DOI 10.1109/ICSM.2008.4658077)
- (en) Knodel Jens, Muthig Dirk, Haury U. et Meier G., « Architecture Compliance Checking - Experiences from Successful Technology Transfer to Industry », Software Maintenance and Reengineering, 2008. CSMR 2008. 12th European Conference, , p. 43 - 52 (ISBN 978-1-4244-2157-2, ISSN 1534-5351, DOI 10.1109/CSMR.2008.4493299)
- (en) Allon Adir, Sigal Asaf, Laurent Fournier, Itai Jaeger et Ofer Peled, « A framework for the validation of processor architecture compliance », Proceedings of the 44th annual Design Automation Conference, , p. 902-905 (ISBN 978-1-59593-627-1, DOI 10.1145/1278480.1278702)
- (en) Baldassarre M.T., Bianchi A., Caivano D. et Visaggio C.A., « Full reuse maintenance process for reducing software degradation », Software Maintenance and Reengineering, 2003. Proceedings. Seventh European Conference, , p. 289 - 298 (ISBN 0-7695-1902-4, ISSN 1534-5351, DOI 10.1109/CSMR.2003.1192437)
- (en) Claire Dimech et Dharini Balasubramaniam, « Maintaining Architectural Conformance during Software Development: A Practical Approach », Software Architecture, vol. 7957, , p. 208-223 (ISBN 978-3-642-39030-2, DOI 10.1007/978-3-642-39031-9_19)
- (en) Jilles van Gurp et Jan Bosch, « Design erosion: problems and causes », Journal of Systems and Software, vol. 61, , p. 105-119 (DOI 10.1016/S0164-1212(01)00152-2)
- (en) David Lorge Parnas, « Software aging », Proceeding ICSE '94 Proceedings of the 16th international conference on Software engineering, , p. 279-287 (ISBN 0-8186-5855-X)
- (en) Sebastian Herold, « Checking architectural compliance in component-based systems », Proceedings of the 2010 ACM Symposium on Applied Computing, , p. 2244-2251 (ISBN 978-1-60558-639-7, DOI 10.1145/1774088.1774558)
- (en) Aldrich J., Chambers Craig et Notkin D., « ArchJava: connecting software architecture to implementation », Proceedings of the 24rd International Conference, , p. 187-197 (ISBN 1-58113-472-X)