Published by

Il y a 13 ans -

Temps de lecture 8 minutes

SonarJ – Comment gérez-vous votre architecture et votre qualité technique ?

L’analyse statique de code consiste à détecter automatiquement des erreurs dans le code source d’un programme sans l’exécuter. Les revues de code, tests statiques automatisés du code sont entrés dans les mœurs du développement logiciel. Ils sont d’ailleurs intégrés dans la majorité des outils d’intégrations continues et constituent, la plupart du temps, l’une des seules métriques permettant de mesurer la santé d’une application en cours de développement. Force est de constater que pour nombre de projets, l’assurance qualité se résume à ces seules métriques.

Ceci est d’autant plus regrettable que la majorité du temps, l’assurance qualité n’est pas considérée à sa juste valeur. On fait encore trop d’assurance qualité afin de se rassurer à court terme « Regardez comme mon code est joli, tous les indicateurs sont aux verts ! ». D’ailleurs, la majorité des outils d’analyse de code fonctionne de manière locale : on assure que la classe courante ne contient pas (trop) de bugs, mais rien n’est prévu pour mesurer la maintenabilité globale de l’application. Avec les outils d’analyse statique de code (PMD / Checkstyle / Findbugs, …), on sait contrôler le code source, mais pas l’architecture applicative.

Erosion de l’architecture

Pourtant, contrôler l’architecture d’un logiciel est difficile. C’est bien beau de définir des beaux principes architecturaux et de communiquer aux équipes de développement, mais sans contrôle, il ne faut pas s’étonner que ces règles ne soient pas respectées. D’une manière générale, on sait comment cela se passe :

  • Une équipe d’architecture définit une liste de « recommandations ». Notez que la bataille est déjà perdue d’avance, avec un tel mot (recommandations) ils nous dévoilent qu’eux-mêmes ne croient pas à l’application de leurs règles.
  • Ensuite, un chef de projet se sent obligé de suivre un minimum la liste de ces règles. Règles dont il ne comprend pas, pour certaines, les raisons de ces choix. Difficile de faire appliquer des règles à une équipe de développement lorsque l’on n’y croit pas soi-même.
  • Finalement, les développeurs, pleins de bonne volonté, essayent d’appliquer ces règles. Ca fonctionne au début, lorsque la bête est encore domptable, mais au fur et à mesure que le projet grandit, le nombre d’erreurs s’accumule. Vous connaissez la suite, la pression des deadlines n’aidant pas, un chef vous supplie de sauver la vie de projet en patchant ici et tout de suite un problème majeur / urgent / bloquant. Bien entendu ce n’est qu’un patch temporaire … patch qui au final deviendra évidemment permanent.

Avec un tel fonctionnement, comment espérez-vous maintenir l’application dans un état serein. À qui la faute ? Bien évidemment, tous les projets ne sont pas comme cela, heureusement. Il s’agit ici d’une caricature … mais au final, ne vous êtes pas reconnu en partie dans cette description ?
Vous voyez ici à quel point il est difficile de garantir une bonne structure et un haut niveau de qualité tout en gardant le contrôle sur sont architecture.

  • L’érosion de l’architecture est un problème connu.
  • Les connaissances et compétences sur un système ne sont pas uniformément réparties.
  • La complexité croît plus vite que la taille du système.
  • Des dépendances non souhaitées et sont crées sans être détectées.

Cette érosion, le fort degré de couplage et le nombre de dépendances cycliques rendent les mises à jour et corrections de plus en plus difficiles dans une application : il devient de plus en plus difficile de tester et comprendre le code.

Les contres mesures

La détection manuelle des écarts et anomalies d’architecture s’avère évidemment inefficace. Les outils comme pbm / checkstyle / findbugs aident peu au niveau de l’architecture, mais reste toujours plus efficace que les revues de code manuelles. Maintenir et vérifier quelques métriques clés permet de détecter certains problèmes suffisamment tôt si vous les avez mises en place des le début de projet. Une technique simple permet de réduire la complexité d’un projet : le découper ! La fameuse devise « Divisez pour régner » fonctionne, mais possède ses inconvénients : ce qu’elle vous fait gagner en complexité, vous le perdez en flexibilité. En règle général, plus vos sous-projets sont petits moins vous êtes flexible. Enfin, vous pouvez éviter les cycles entre les packages en utilisant JDepend, mais cet outil n’est pas parfait : le niveau d’abstraction est beaucoup trop bas et il ne peut vérifier automatiquement la structure de votre code.

SonarJ – un début de solution

Si on récapitule, de quoi avons-nous besoin ? Nous avons besoin d’un moyen simple de décrire notre architecture et certaines règles pour vérifier la qualité à un haut niveau d’abstraction, d’un nombre réduit de métriques permettant de garder la qualité technique sous contrôle. Nous avons également besoins de patterns simples d’architecture permettant de garder un couplage faible et une structure simple : principe d’inversions des dépendances et d’un outil qui permet à chaque développeur de vérifier lui-même si le refactoring de code ou ajout de fonctionnalité provoque des violations d’architecture.

Aparté : comment le pattern d’injection de dépendances permet de réduire le couplage ?

L’ACD (Average Component Dependency) permet de mesure le couplage : voici comment le calculer. L’ACD représente le nombre moyen de dépendances directe et indirecte sur un objet. Pour l’obtenir, il suffit donc de compter ces dépendances. Dans l’exemple ci-dessous, on a calculé l’ACD d’un même système utilisant ou non un pattern d’injection de dépendances type Spring.

SonarJ permet d’effectuer tout cela, le contrôle de l’architecture passe par la définition d’un modèle logique. La création de ce domaine passe par 3 étapes :

  1. Découpage en couches horizontales. Les couches horizontales représentent les différents ‘layers’ de votre application ; il s’agit des mêmes layers que vous avez l’habitude d’utiliser : model / dao / services … Il est possible d’ajouter des contraintes entre ses couches : autoriser l’utilisation à la couche dao uniquement à partir de la couche service. Dans le cas où une autre couche utiliserait un des éléments de la couche dao, une violation d’architecture serait détectée.
  2. Découpage en tranches verticales pour les aspects fonctionnels. L’idée est de découper l’application en domaines fonctionnels : les tranches verticales. L’exhaustivité des fonctionnalités n’est pas nécessaire dès la mise en place du modèle. Si vous effectuez la création du modèle alors que le développement de l’application est déjà commencé, nous recommandons de travailler par itérations afin de ne pas être noyés par le travail à effectuer. Comme pour les couches, il est également possible d’ajouter des contraintes d’utilisation d’une tranche sur une autre.
  3. Définition des règles d’engagement. Le croisement des couches et des tranches permet l’émergence de sous systèmes. Chaque sous-système appartient à exactement une couche et peut appartenir à une tranche verticale. Les tranches verticales n’ont pas à être présentes dans chaque couche horizontale. Typiquement, les sous-systèmes techniques ne sont associés à aucune tranche verticale. L’association entre une tranche verticale et des sous-systèmes est typiquement implémentée par une convention de nommage. Chaque package est mappé exactement dans un sous-système. Si des packages contiennent des types de plusieurs sous-systèmes, les refactorings virtuels (simulation) sont utiles.

Notons l’importance de disposer d’une convention de nommage, si les règles sont définies et appliquées, le mapping entre les packages et les sous-systèmes sera facilité par l’utilisation d’expression régulière. Sans cela, le travail s’avérera particulièrement fastidieux.

Une fois le modèle d’architecture créé, il ne vous reste plus qu’à comparer le code de l’application à celui-ci. Cette comparaison peut s’effectuer de plusieurs manières :

  • directement via SonarJ en important un workspace projet
  • sur les postes des développements via un plugin eclipse : sonarclipse
  • lors du processus d’intégration continue via des tâches Ant et Maven spécifiques

Il vous est également possible de générer les rapports ‘snapshots’ et diagrammes ‘historiques’ des violations d’architecture, voire de lier ces rapports à un outil de gestion d’incidents : Jira / Codebeamer …

Conclusion

Pour conclure, SonarJ offre un moyen de contrôler l’architecture d’un système. Son utilisation est largement facilité si une bonne convention de nommage est définit, dans le cas contraire la mise à jour systématique du modèle d’architecture peut s’avérer rébarbatif. En plus des violations d’architecture d’accès d’un sous-système à une autre. SonarJ permet également de détecter les cycles entres les packages d’une application, de mettre des alertes sur des métriques : (par exemple : créer une alerte si une classe dépasse 500 lignes de codes / créer une alerte si la complexité cyclomatique d’une méthode dépasse 15 …).

  • Consultez le site officiel de SonarJ
  • Getting Started with SonarJ : consultez la vidéo
  • Consultez le site du distributeur exclusif en france

 

Définition des couches                 Définition des tranches verticales                 Définition des sous-systèmes
screen_layer.jpg screen_vertical.jpg screen_subs.jpg
Détection des cycles entre packages                  Recherche de complexité cyclomatique                 Sonarclipse
screen_cycles.jpg screen_cyclo.jpg screen_sonarclipse.jpg

 

Published by

Publié par Erwan Alliaume

Passionné par les technologies Java/JEE depuis sa sortie de l'EPITA, Erwan Alliaume est aujourd'hui consultant chez Xebia. Il intervient depuis 2 ans sur des missions de développement et d'architecture pour l’un des leaders mondiaux de la production et de la distribution de contenus multimédia. Expert technique polyvalent, Erwan a été amené très tôt à prendre des responsabilités sur des projets de taille significative. Il a notamment développé des compétences clé dans la mise en place de socle de développement, la métrologie et les audits de performance et de qualité. Erwan participe également activement au blog Xebia ou il traite aussi bien de sujets d’actualités que de problématiques techniques.

Commentaire

3 réponses pour " SonarJ – Comment gérez-vous votre architecture et votre qualité technique ? "

  1. Published by , Il y a 13 ans

    Très bon article.

    Je suis complétement d’accord sur votre partie de définition des « recommandations ». C’est un sujet à la mode dans les grandes entreprises. Ces recommandations sont utilisées pour se couvrir à posteriori et flinguer plus facilement les pauvres développeurs qui n’ont pas lus les 10 Recommandations du Grand Architecte… SonarJ a l’intelligence de travailler en amont et d’améliorer la qualité du code et le respect de l’architecture.

  2. Published by , Il y a 13 ans

    La qualité technique peut aussi être en partie contrôlée via des règles de CheckStyle et un IDE comme Eclipse qui va râler si les règles ne sont pas respectées.

    Mais cette technique a ses limites… Surtout si l’on souhaite vérifier des règles de plus haut niveau comme vous l’évoquez dans votre très bon article.

  3. Published by , Il y a 11 ans

    C’est vrai que « coder » les règles d’architecture dans un fichier Word ne sert pas à grand chose, sinon peut être à se donner bonne conscience, du moins, au départ.

    D’un autre coté, si je comprends l’utilité de SonarJ, force est de constater que les problèmes qui sont découverts proviennent du fait qu’il existe des frontières et des dépendances **implicites** entre différentes parties du code.
    Ces frontières+dépendances sont implicites avec le mode de développement classique d’une application web (avec déploiement EAR).

    Par contre, si les applications web étaient développées en utilisant OSGi, soit par le biais des dépendances **explicites** entre modules, les règles d’architecture seraient mieux respectées (contraintes OSGi obligent). Et SonarJ aurait moins d’utilité.

    Vivement que OSGi soit de plus en plus utilisé coté serveur.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Nous recrutons

Être un Sapient, c'est faire partie d'un groupe de passionnés ; C'est l'opportunité de travailler et de partager avec des pairs parmi les plus talentueux.