Un reengineering ne signifie pas toujours dans l’esprit de chacun, la réécriture de notre application Legacy dans un autre langage généralement plus récent, mais c’est néanmoins l’option que nous avons choisie.
Lorsqu’il s’agit ‘simplement’ de réorganiser le code afin de rendre celui-ci plus maintenable, mais sans le porter sur une nouvelle plate-forme logicielle ou hardware – comme par exemple la migration d’une application Mainframe-Cobol vers une architecture Unix – je préfère parler de refactoring.
Je vous rappelle que ce blog n’a pas de prétentions académiques, donc je ne vais pas m’embarrasser de définitions méticuleusement exactes, qui débouchent le plus souvent sur des discussions quadripilotectomiques (1) de spécialistes qui n’ont rien d’autre à faire que de gloser sur la moindre virgule.
Mais ceci n’interdit pas un minimum de précision, afin d’éviter préconceptions et autres malentendus. Nous avons d’abord regardé quelles actions de refactoring nous pouvions envisager pour notre application Legacy en C (Word 1.1a) à l’aide du plugin SQALE. Puis nous avons tenté une estimation du coût de ces actions et un calcul de ROI.
Aujourd’hui, je vais évoquer quelques éléments à prendre en compte lorsque l’on envisage un reengineering.
Objectifs
La stratégie produit ou applicative est évidemment au cœur d’un plan de réingénierie : plateforme logicielle et/ou hardware trop coûteuse ou en fin de vie, rareté des compétences informatiques pour maintenir l’application sur cette plate-forme, coûts de maintenance trop élevés, etc. Mais dans tous les cas, on souhaite conserver l’application, ou le produit logiciel dans le cas d’un vendeur de software, et non pas l’abandonner en le remplaçant par un progiciel ou le développement d’une nouvelle application, ou en le sortant du catalogue pour un éditeur.
L’étape préalable à une réingénierie consiste donc en une identification claire des objectifs.
Or, contrairement à ce que l’on pourrait croire, un reengineering n’est pas toujours un objectif conscient. Bien sûr, si votre Directeur Informatique en a assez de voir chaque année des commerciaux lui annonçaient :
- la fin proche de tel logiciel ou plateforme ET,
- la nécessité d’acquérir en remplacement tel nouveau software ET,
- de démarrer un projet d’implémentation avec leurs consultants, tous aussi experts que onéreux, ET
- la nécessité d’upgrader son infrastructure informatique afin de conserver un niveau de performance acceptable pour cette nouvelle plateforme logicielle ET
- une nouvelle tarification à la hausse, ALORS
il pourrait bien envisager un bouleversement technologique majeur afin de remettre la main sur son informatique et qu’on cesse de le traiter comme une vache à lait.
Cependant, j’ai vu nombre de cas où le reengineering n’était pas envisagé à l’origine, mais s’est imposé comme un choix nécessaire et incontournable à la suite d’une série de découvertes, de réflexions et de décisions plus ou moins bien formalisées.
Reengineering et portefeuilles applicatifs
J’ai fait un audit pour une banque, ou plutôt pour sa division ‘Asset Managemet’ qui s’occupe de la gestion d’actifs financiers, avec une application dont le nombre de clients devait être multiplié par trois. Qui dit 3 fois plus d’utilisateurs dit également 3 fois plus de données, et 3 fois plus (en moyenne) de connexions à une base de données 3 fois plus importante. D’où un souci de performance de la part de cette banque. Leur première réaction a été de chercher un outil de tests de charge, puis ils ont commencé à se demander s’il était possible de détecter dans le code d’éventuels défauts de programmation qui pourraient menacer les futurs temps de réponse.
Si me souviens bien, il s’agissait d’une application en Visual Basic et, pour les raisons habituelles de confidentialité, ils ne souhaitaient pas me confier le code entier de leur application. Ce qui pose toujours un problème car moins vous avez de code, moins vous pouvez rencontrer de défauts dans le code et plus il est difficile de démontrer la valeur que vous pouvez apporter.
Je leur donc ai proposé d’analyser un module de leur application, mais également de me livrer du code J2EE et Cobol, avec un objectif principal centré sur l’identification de risques potentiels pour la performance, et un second objectif sur la mesure de la maintenabilité. Qui ne les intéressait pas beaucoup, il m’a vraiment fallu insister. Mais quand j’ai présenté les résultats, ils sont restés assez impressionnés, et quelqu’un dans la pièce a dit : « il faut présenter cela au CIO ».
En fait, outre leur souci de performance sur cette application, le CIO avait surtout une préoccupation de rénovation de son portefeuille applicatif, dont il ressentait bien qu’il débordait d’applications pas toujours très critiques, mais souvent peu maintenables, et sans savoir par où commencer. Nous avons eu une seconde réunion à laquelle il a participé, et dans laquelle nous avons pratiquement construit en ‘live’ un plan de refactoring de l’application Cobol et la réingénierie de l’application Visual Basic.
Conclusion : certains ‘use cases’ peuvent mener à un refactoring et un reengineering qui n’étaient pas initialement un objectif. Un outil d’analyse et de mesure de la qualité de code est nécessaire pour savoir quelles applications de votre portefeuille applicatif pourront bénéficier d’une réingénierie, et par où commencer.
Reengineering d’outils maison
Parfois le reengineering portera simplement sur une partie de l’application. Au début des années 90, avec la survenance du client-serveur et des premières applications à interface graphique, nombre d’entreprises ont développé leur propre middleware afin d’assurer des échanges (asynchrones ou non) entre leur mainframe et ces nouvelles applications. Une équipe dédiée se chargeait de développer et de maintenir ce middleware, en délivrant régulièrement les APIs et la documentation qui permettaient son utilisation par les équipes de projet.
Le problème est que, comme toute application, ce code accumulait de la dette technique, et la maintenance de cet outil devenait de plus en plus lourde, les corrections et les évolutions demandées par les projets de plus en plus longues et coûteuses à implémenter, la documentation plus difficile à maintenir, et la connaissance se perdait au fur et à mesure que les membres de l’équipe progressaient vers d’autres postes ou simplement quittaient l’entreprise. Donc est arrivé un moment où ce middleware maison a laissé place à un outil de type MOM, ESB, EAI, voire à une nouvelle architecture type SOA ou EDA (2). Non, ne me demandez pas de définition, j’ai dit en début de ce post que ce blog n’était pas un dictionnaire !
Bien évidemment, il a fallu encapsuler ce nouvel outil dans les APIs existantes, afin d’impacter le moins possible les applications qui utilisaient ces dernières. Comme le middleware maison était le plus souvent programmé avec un langage de type L3G, mais aussi il faut bien le dire, face à l’enthousiasme de l’équipe ‘middleware’ pour les nouvelles technologies, bon nombre de ces APIs ont été réécrites, souvent à l’identique, mais en tout cas avec des langages Orientés Objet.
Reengineering et interfaces utilisateur
Un cas très fréquent de réingénierie concerne les applications avec une interface utilisateur vieillotte ou obsolète. Cela a été le cas de nombre d’applications mainframe avec une interface caractère, qui ont été portées (non sans mal) sous Windows. Il existait même à une certaine époque, des outils de génération d’écrans, qui reprenaient des ‘grilles’ mainframe pour les transformer en écrans Windows, avec des résultats assez comiques (sauf pour les utilisateurs finals).
La bulle Internet et les sites Web ont causé beaucoup de dégâts en ce qui concerne le respect des normes d’interface graphiques, mais avec les applications pour smartphone, on découvre à nouveau l’importance de ces normes, même si sous un vocable plus moderne de UX (User Experience).
Donc nombre d’applications connaissent une réingénierie de leur couche de présentation afin d’être accessibles aussi bien sur le Web que sur votre mobile. Les éditeurs logiciels doivent également effectuer ce type de projet assez fréquemment. Une interface HTML dépassée est un véritable poids mort lorsqu’il s’agit de vendre un software et nécessitera un relooking dans une nouvelle technologie : Flex ou HTML5 par exemple.
Ce qui pose parfois des problèmes. Essayez donc de sélectionner une ou plusieurs lignes d’un tableau Flex pour effectuer un copier-coller : les utilisateurs vont avoir du mal à comprendre que vous ayez adopté une technologie plus récente qui ne lui permette pas des opérations aussi basiques.
Bien souvent, un éditeur logiciel ne va pas interpréter cette évolution de l’interface graphique comme un reengineering mais simplement comme une nouvelle version de son software, avec des écrans plus jolis. S’il le faisait, s’il l’identifiait comme un objectif clair de migration vers une nouvelle technologie et une interface graphique différente, il pourrait peut-être réfléchir aux impacts pour les utilisateurs en termes de modes opératoires au lieu d’attendre que ceux-ci les découvrent quand il est trop tard.
Périmètre
Comme on peut le voir à travers les exemples précédents, il est important d’avoir des objectifs clairs et même formalisés, afin d’éviter des conséquences inattendues. Notamment parce que ces objectifs vont conditionner la question suivante : réingénierie à l’équivalent, c’est-à-dire avec un même périmètre fonctionnel, ou avec de nouvelles fonctionnalités ?
Un reengineering est un projet souvent complexe, qui nécessite une bonne connaissance de l’application originale et des parties de code plus difficiles à lire et à comprendre, une bonne expertise de la nouvelle plateforme cible, une estimation précise de la dette technique afin de procéder à une évaluation correcte de l’effort et du planning, un minimum de documentation et si possible, de couverture de tests.
Comme c’est rarement le cas, l’équipe de projet va souhaiter limiter les risques en évitant d’introduire des nouvelles fonctionnalités dans l’application. Or les utilisateurs vont probablement se montrer très insistants sur ce point puisque, dans le cas contraire, ils devront non seulement attendre la fin du reengineering mais également le développement d’une version suivante qui incorpore ces nouvelles fonctionnalités.
Malheureusement pour l’équipe de projet, ce sont souvent les utilisateurs qui auront gain de cause, tout simplement parce qu’il est généralement impossible de réécrire une application sans se heurter à des problèmes techniques qu’il faudra contourner par de nouveaux processus et/ou une nouvelle conception des fonctionnalités métier.
Par exemple, si vous modifiez l’interface utilisateur, vous modifiez vraisemblablement les données disponibles à l’écran. Combien de fois ai-je vu, lors d’un reengineering, de multiples écrans remplacés par un écran unique composé de multiples onglets ? Evidemment, il faut alors modifier en conséquence les traitements d’accès à la couche de données, ce qui peut provoquer des problèmes de temps de réponse. S’il n’est pas possible de régler ceux-ci d’un point de vue technique (avec un upgrade de l’infrastructure technique par exemple), alors vous devez demander aux utilisateurs s’il serait possible de réaliser cette opération métier de manière différente, afin de charger moins de données dans l’écran.
Autre cas à prendre en compte : une réingénierie ne porte pas que sur le code et les traitements, mais aussi sur les données. Un nouveau design des classes et des programmes aura pour corollaire les modifications correspondantes en termes de structures de données.
Si un programme unique attaque une table monstre en base de données, vous allez souhaitez découper ce programme et cette table en entités de granularité plus petite, pour une meilleure maintenabilité et probablement une performance accrue.
Plus simplement, vous allez profiter de la ré-écriture de l’application pour modifier certains types de données. Parce que l’utilisateur a déjà demandé certaines évolutions faciles à prendre en compte, comme modifier la taille d’un champ ou la précision de certains chiffres. Ou c’est vous qui allez le trouver pour lui demander s’il a réellement besoin d’un champ de commentaires aussi large alors qu’il n’est pratiquement jamais utilisé.
Donc, pour votre plan projet de réingénierie :
- Planifiez bien le re-design des traitements mais également des données.
- Prévoyez des modifications au niveau des processus métier.
- Associez un ou plusieurs utilisateurs au projet, afin qu’ils soient disponibles pour toute question de processus, de traitements métier ou de réingénierie des données.
- N’écartez pas toutes les demandes d’évolution fonctionnelle, mais étudiez bien celles qui sont susceptibles d’impacter votre projet ou d’être réalisées facilement au cours de celui-ci.
Et surtout, soyez toujours bien conscient des objectifs de votre reengineering.
1. Tétrapilectomie Coupage de cheveux en 4. Néologisme inventé par Umberto Eco et son groupe de pataphysiciens. Formé du préfixe grec tétra- (‘quatre ‘), du latin pilus (‘poil, cheveu’) et de -ectomie (coupe, inciser).
2. MOM : Message Oriented Middleware. ESB : Enterprise Service Bus. EAI : Enterprise Application Integration. SOA : Service Oriented Architecture. EDA : Event-Driven Architecture.
Cette publication est également disponible en Leer este articulo en castellano : liste des langues séparées par une virgule, Read that post in english : dernière langue.