{"id":2222,"date":"2014-11-17T05:07:14","date_gmt":"2014-11-17T04:07:14","guid":{"rendered":"http:\/\/qualilogy.com\/fr\/?p=2222"},"modified":"2014-11-17T06:11:39","modified_gmt":"2014-11-17T05:11:39","slug":"application-legacy-reengineering-avec-sonarqube","status":"publish","type":"post","link":"http:\/\/qualilogy.com\/fr\/application-legacy-reengineering-avec-sonarqube\/","title":{"rendered":"Application Legacy \u2013 Reengineering avec SonarQube"},"content":{"rendered":"<p><a href=\"http:\/\/500px.com\/Vicken\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-2223\" src=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/11\/LegacyApp_ReengineeringWithSQ2.jpg\" alt=\"Application Legacy - R\u00e9ingenierie avec SonarQube\" width=\"239\" height=\"360\" srcset=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/11\/LegacyApp_ReengineeringWithSQ2.jpg 239w, http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/11\/LegacyApp_ReengineeringWithSQ2-199x300.jpg 199w\" sizes=\"(max-width: 239px) 100vw, 239px\" \/><\/a>Nous avons d\u00e9fini notre projet de r\u00e9ing\u00e9nierie comme la r\u00e9\u00e9criture de notre application Legacy dans un nouveau langage ou son portage vers une nouvelle technologie, par opposition \u00e0 un refactoring qui consiste \u00e0 r\u00e9organiser le code et \u00e0 en corriger certains d\u00e9fauts afin de rendre celui-ci plus maintenable et de r\u00e9duire sa dette technique.<\/p>\n<p>Nous avons vu \u00e9galement, \u00e0 l\u2019aide de <a title=\"Application Legacy \u2013 Refactoring avec le plugin SQALE (II)\" href=\"http:\/\/qualilogy.com\/fr\/application-legacy-refactoring-plugin-sqale-2\/\" target=\"_blank\">SonarQube et du plugin SQALE<\/a>, diff\u00e9rents plans de refactoring plus ou moins ambitieux, depuis la r\u00e9solution des d\u00e9fauts les plus critiques jusqu\u2019\u00e0 la r\u00e9duction de la dette technique afin de ramener celle-ci \u00e0 un niveau (rating SQALE) \u2018A\u2019.<\/p>\n<p>Cependant, pour une m\u00eame application Legacy, est-il plus int\u00e9ressant d\u2019effectuer un projet de r\u00e9ing\u00e9nierie ou \u2018simplement\u2019 de refactoring ? <!--more--><\/p>\n<p>Normalement, l\u2019investissement sera sup\u00e9rieur pour un reengineering, puisqu\u2019il est rarement envisageable de pouvoir moduler celui-ci, sauf dans le cas d\u2019une r\u00e9ing\u00e9nierie partielle, de l\u2019interface graphique par exemple, alors qu\u2019un refactoring peut se moduler au fil du temps.<\/p>\n<p>Mais on peut supposer que les b\u00e9n\u00e9fices d\u2019un reengineering seront \u00e9galement largement sup\u00e9rieurs \u00e0 ceux d\u2019un refactoring puisque la dette technique devrait, non pas dispara\u00eetre compl\u00e8tement \u2013 il restera toujours des objets complexes ou des d\u00e9fauts d\u2019inattention &#8211; mais du moins se r\u00e9duire tr\u00e8s fortement. Ceci dans le cas o\u00f9 le projet de r\u00e9ing\u00e9nierie est un succ\u00e8s bien \u00e9videmment.<\/p>\n<p>Car les risques d\u2019\u00e9chec sont importants :<\/p>\n<ul>\n<li>Vous ne ma\u00eetrisez pas la nouvelle plate-forme technique ou le langage cible, vous manquez de connaissances ou d\u2019expertise dans ce domaine. Votre nouvelle application rencontre des probl\u00e8mes de temps de r\u00e9ponse.<\/li>\n<li>Vous avez mal calcul\u00e9 l\u2019effort de reengineering, vous d\u00e9veloppez rapidement et oubliez les tests unitaires, afin de tenir les d\u00e9lais de projet. Votre nouvelle application est bogu\u00e9e.<\/li>\n<li>Certains modes op\u00e9ratoires ou processus fonctionnels sont modifi\u00e9s, sous pr\u00e9texte de simplification, mais en fait pour all\u00e9ger la charge de r\u00e9ing\u00e9nierie. Votre nouvelle application ne r\u00e9pond pas aux exigences m\u00e9tier et s\u2019av\u00e8re plus complexe \u00e0 utiliser.<\/li>\n<li>Vous n\u2019avez pas identifi\u00e9s pr\u00e9cis\u00e9ment les objectifs, les utilisateurs ne sont pas incorpor\u00e9s au projet. Vous faites face \u00e0 de nombreuses demandes de leur part et vous explosez votre budget et votre planning.<\/li>\n<\/ul>\n<p>Performance d\u00e9sastreuse, dysfonctionnements, utilisateurs m\u00e9contents : nous allons voir quelques points \u00e0 prendre en compte afin de limiter ces risques et comment SonarQube peut nous aider.<\/p>\n<h2>Divide and Conquer<\/h2>\n<p>Nous avons vu que SonarQube permettait <a title=\"Audit d\u2019une application Legacy en C \u2013 Microsoft Word 1.1a (I)\" href=\"http:\/\/qualilogy.com\/fr\/audit-application-legacy-c-microsoft-word-1-1a-1\/\" target=\"_blank\">une vue g\u00e9n\u00e9rale sur l\u2019application<\/a>, notamment en mati\u00e8re de m\u00e9triques quantitatives telles que le nombre de lignes de code (LOC), la Complexit\u00e9 Cyclomatique (CC), le niveau de commentaires dans le code, etc.<\/p>\n<p>Nous avons ensuite <a title=\"Application Legacy \u2013 Refactoring ou reengineering? (V)\" href=\"http:\/\/qualilogy.com\/fr\/application-legacy-refactoring-reengineering-5\/\" target=\"_blank\">zoom\u00e9 sur ces composants<\/a> afin d\u2019identifier les fonctions et programmes les plus complexes et les d\u00e9fauts rencontr\u00e9s dans leur code.<\/p>\n<p>Nous avons jou\u00e9 \u00e9galement avec certains widgets, et notamment <a title=\"Application Legacy \u2013 Refactoring avec le plugin SQALE (I)\" href=\"http:\/\/qualilogy.com\/fr\/application-legacy-refactoring-plugin-sqale-1\/\" target=\"_blank\">le Bubble Chart<\/a> afin de croiser certaines de ces m\u00e9triques entre elles ou avec la dette technique, et distinguer les programmes monstrueux qui constituent la cible privil\u00e9gi\u00e9e de notre r\u00e9engineering.<\/p>\n<p style=\"text-align: center\">\u00a0<strong><em>Figure 1 \u2013 Technical Debt x Cyclomatic Complexity\/Function x Lines of Code<\/em><\/strong><a href=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/10\/LegacyTechDebtBubbles3.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2111\" src=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/10\/LegacyTechDebtBubbles3.jpg\" alt=\"Technical Debt x Cyclomatic Complexity\/Function x Lines of Code\" width=\"833\" height=\"518\" srcset=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/10\/LegacyTechDebtBubbles3.jpg 833w, http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/10\/LegacyTechDebtBubbles3-300x186.jpg 300w, http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/10\/LegacyTechDebtBubbles3-624x388.jpg 624w\" sizes=\"(max-width: 833px) 100vw, 833px\" \/><\/a><\/p>\n<p style=\"text-align: left\">Dans la figure pr\u00e9c\u00e9dente, on note imm\u00e9diatement le fichier \u2018RTFOUT.C\u2019, de par la taille de la bulle qui repr\u00e9sente la Complexit\u00e9 Cyclomatique (CC) moyenne des fonctions de ce programme. Mais le fichier &lsquo;fltexp.c&rsquo; tout en haut poss\u00e9de la dette technique la plus \u00e9lev\u00e9e, avec une CC moyenne par fonction moins importante, tout simplement parce qu&rsquo;il compte plus de fonctions.<\/p>\n<p style=\"text-align: left\">Un tel graphique nous permet de visualiser imm\u00e9diatement les programmes avec une taille en nombre de lignes de code \u00e9lev\u00e9e, comportant des fonctions complexes et une dette technique importante. Il nous est alors possible d\u2019examiner comment les d\u00e9couper en plusieurs composants de granularit\u00e9 moins importante afin de r\u00e9duire leur complexit\u00e9, am\u00e9liorer leur lisibilit\u00e9 et leur maintainabilit\u00e9.<\/p>\n<p style=\"text-align: left\">Nous avons vu par exemple <a title=\"Application Legacy \u2013 Refactoring ou reengineering? (V)\" href=\"http:\/\/qualilogy.com\/fr\/application-legacy-refactoring-reengineering-5\/\" target=\"_blank\">la fonction &lsquo;monstre&rsquo; du programme &lsquo;RTFOUT.C&rsquo;<\/a> qui s\u2019occupe \u00e0 elle seule de g\u00e9rer le Rich Text Format (RTF) de Microsoft. Diff\u00e9rents blocs de code prennent en charge les param\u00e8tres concernant les polices de caract\u00e8res, les fontes (gras, italique, etc.), les propri\u00e9t\u00e9s du document (auteur, nombre de mots ou de lignes, etc.), \u2026 Il est donc assez facile de sp\u00e9cialiser ce code au sein de fonctions ou de classes distinctes.<\/p>\n<p style=\"text-align: left\">Deux points importants pour ce red\u00e9coupage fonctionnel :<\/p>\n<ul>\n<li style=\"text-align: left\">Les tests unitaires : si on en a d\u00e9j\u00e0, il faudra probablement les modifier afin de les adapter \u00e0 notre nouveau design. Si on n\u2019en a pas, ou s\u2019ils ne sont pas compatibles ou utilisables avec notre nouveau langage cible, il faudra les (r\u00e9-) \u00e9crire au fur et \u00e0 mesure dans le nouveau langage.<\/li>\n<li style=\"text-align: left\">Il n\u2019est pas n\u00e9cessaire de r\u00e9duire compl\u00e8tement la Complexit\u00e9 Cyclomatique (CC) : on peut se permettre d\u2019avoir quelques composants tr\u00e8s complexes, mais pas trop. Par exemple, une classe unique pour g\u00e9rer toutes les variables \u2018utilitaires\u2019 ou les constantes, avec autant de m\u00e9thodes (en fait, autant de setters\/getters), aura une CC proportionnelles au nombre de ces donn\u00e9es et m\u00e9thodes, mais en fait restera tr\u00e8s lisible et facilement maintenable.<\/li>\n<\/ul>\n<p style=\"text-align: left\">Notre reengineering est en fait proche ici d\u2019un reverse engineering qui consiste \u00e0 comprendre le design actuel afin de repenser celui-ci diff\u00e9remment. Il est souvent int\u00e9ressant de se faire assister pour cela d\u2019un outil d\u2019analyse d\u2019impact afin de dessiner une carte des diff\u00e9rents modules ou packages et des relations entre eux, identifier les liens entre les diff\u00e9rentes couches de l\u2019application (pr\u00e9sentation, logique, donn\u00e9es), visualiser les objets les plus complexes, etc.<\/p>\n<p style=\"text-align: left\">Un outil d\u2019analyse d\u2019impact sera \u00e9galement utile pour identifier du code mort, c\u2019est-\u00e0-dire des objets (classe, m\u00e9thode, table de base de donn\u00e9es, etc.) qui ne sont pas utilis\u00e9s, qui ne sont appel\u00e9s par aucun autre composant. Inutile de r\u00e9\u00e9crire des composants qui ne sont plus utilis\u00e9s.<br \/>\nAttention cependant : ces outils produisent fr\u00e9quemment des false-positives et n\u00e9cessitent de bonnes comp\u00e9tences pour une utilisation optimale.<\/p>\n<h2 style=\"text-align: left\">Code dupliqu\u00e9<\/h2>\n<p style=\"text-align: left\">Pendant que SonarQube me montre le code des fonctions complexes ou tr\u00e8s complexes, je peux en profiter pour noter les blocs de code dupliqu\u00e9s. Dans la figure suivante :<\/p>\n<p style=\"text-align: center\"><em><strong>Figure 2 \u2013 Lignes des blocs de code dupliqu\u00e9s dans SonarQube<\/strong><\/em><\/p>\n<p style=\"text-align: left\"><a href=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/11\/LegacyApp_DuplicatedCode.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2232\" src=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/11\/LegacyApp_DuplicatedCode.jpg\" alt=\"Application Legacy - Lignes de code dupliqu\u00e9 dans SonarQube\" width=\"494\" height=\"242\" srcset=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/11\/LegacyApp_DuplicatedCode.jpg 494w, http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/11\/LegacyApp_DuplicatedCode-300x146.jpg 300w\" sizes=\"(max-width: 494px) 100vw, 494px\" \/><\/a><\/p>\n<p>nous rencontrons deux blocs de 33 lignes copi\u00e9s\/coll\u00e9s aux lignes 1188 et 1255 du programme. Dans d\u2019autres cas, ces duplications interviendront entre diff\u00e9rents fichiers.<\/p>\n<p>Il est important de les identifier assez t\u00f4t car :<\/p>\n<ul>\n<li>Elles sont souvent synonymes d\u2019un design peu optimis\u00e9.<\/li>\n<li>Je peux \u00e9viter de r\u00e9\u00e9crire le m\u00eame bloc de code plusieurs fois dans le nouveau langage cible.<\/li>\n<li>Je diminue la maintenance et les risques pour l\u2019application : toute modification dans du code dupliqu\u00e9 doit \u00eatre report\u00e9e sur chacun de ses exemplaires, ce qui co\u00fbte plus cher en maintenance et accro\u00eet le risque de d\u00e9fauts en cas d\u2019oubli.<\/li>\n<\/ul>\n<h2>Interface utilisateurs<\/h2>\n<p>Nous avons vu que l\u2019interface utilisateur pouvait constituer en elle seule un <a title=\"Application Legacy \u2013 Objectifs d\u2019un reengineering\" href=\"http:\/\/qualilogy.com\/fr\/application-legacy-objectifs-reengineering\/\" target=\"_blank\">objectif de reengineering<\/a>. Dans ce cas, il est important de l\u2019envisager le plus en amont possible car la modification des \u00e9crans peut avoir un double impact :<\/p>\n<ul>\n<li>Modification des donn\u00e9es : auquel cas, il faudra commencer par cette \u00e9tape et ensuite regarder l\u2019impact en termes de classes ou programmes ou fonctions.<\/li>\n<li>Modification des processus m\u00e9tiers : dans ce cas, travaillez le plus t\u00f4t possible avec les utilisateurs afin de valider ces modifications. N\u2019essayez m\u00eame pas de commencer votre reengineering avant cette validation. Et surtout pas de programmer les \u00e9crans \u00e0 l\u2019identique.<\/li>\n<\/ul>\n<p>Attention \u00e0 bien v\u00e9rifier des op\u00e9rations qui ne sont pas n\u00e9cessairement \u2018cod\u00e9es\u2019 dans l\u2019interface graphique. Par exemple, tous les utilisateurs font des Copier\/Coller, et g\u00e9n\u00e9ralement, vous n\u2019avez pas programm\u00e9 un bouton ou un menu pour ce faire. Et l\u2019utilisateur \u00e9voquera rarement ce point car pour lui, c\u2019est naturel et \u00e9vident. Veillez \u00e0 bien identifier ces processus \u2018implicites\u2019 et \u00e0 tester qu\u2019ils sont reproductibles dans la nouvelle version de l\u2019application, apr\u00e8s r\u00e9ing\u00e9nierie.<\/p>\n<p>V\u00e9rifiez la consistance des messages utilisateurs : on normalise, soit autour d\u2019une phrase telle que \u2018Le montant saisi est erron\u00e9\u2019, soit autour d\u2019une expression : \u2018Erreur de saisie du montant\u2019.<\/p>\n<p>V\u00e9rifiez les inconsistances dans les repr\u00e9sentations de donn\u00e9es, parfois avec d\u00e9cimales, parfois sans par exemple.<\/p>\n<p>Suite et fin dans le prochain post: nous verrons comment \u00e9tudier la restructuration des traitements avec SonarQube.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nous avons d\u00e9fini notre projet de r\u00e9ing\u00e9nierie comme la r\u00e9\u00e9criture de notre application Legacy dans un nouveau langage ou son portage vers une nouvelle technologie, par opposition \u00e0 un refactoring qui consiste \u00e0 r\u00e9organiser le code et \u00e0 en corriger certains d\u00e9fauts afin de rendre celui-ci plus maintenable et de r\u00e9duire sa dette technique. Nous [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-2222","post","type-post","status-publish","format-standard","hentry","category-qualite-des-applications"],"_links":{"self":[{"href":"http:\/\/qualilogy.com\/fr\/wp-json\/wp\/v2\/posts\/2222"}],"collection":[{"href":"http:\/\/qualilogy.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/qualilogy.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/qualilogy.com\/fr\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/qualilogy.com\/fr\/wp-json\/wp\/v2\/comments?post=2222"}],"version-history":[{"count":13,"href":"http:\/\/qualilogy.com\/fr\/wp-json\/wp\/v2\/posts\/2222\/revisions"}],"predecessor-version":[{"id":2225,"href":"http:\/\/qualilogy.com\/fr\/wp-json\/wp\/v2\/posts\/2222\/revisions\/2225"}],"wp:attachment":[{"href":"http:\/\/qualilogy.com\/fr\/wp-json\/wp\/v2\/media?parent=2222"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/qualilogy.com\/fr\/wp-json\/wp\/v2\/categories?post=2222"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/qualilogy.com\/fr\/wp-json\/wp\/v2\/tags?post=2222"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}