On vous explique le contexte : Deux jeunes développeurs fraîchement sortis des bancs de l’école apprennent qu’ils vont travailler sur un sujet from scratch à vocation open-source pouvant potentiellement améliorer le quotidien de nombreux développeurs et développeuses. Le tout en découvrant plein de nouvelles technologies et de nouvelles pratiques : le rêve.
Quelques mois après la fin de notre stage, nous allons donc vous faire part de notre expérience tout en vous dévoilant l’outil que nous avons développé : Candy-Doc.
Candy-Doc c’est quoi ?
Candy-Doc est un outil qui rend vivante la documentation d'un projet en extrayant les concepts métier du code source.
Pour une première version, nous nous appuyons sur les concepts d’architecture du Domain-Driven Design car ils permettent de représenter le métier avec précision. Et comme nous venons du monde Java, nous l'avons fait sous forme de plugin Maven.
Pourquoi Candy-Doc ?
Candy-Doc a vu le jour pour deux principales raisons.
Un besoin de documenter
La documentation est souvent un sujet sensible pour les développeurs. C’est une étape fastidieuse du développement mais nécessaire. Elle apporte non seulement une compréhension du code mais également de la logique du système décrit.
La documentation devient cependant obsolète dès lors qu’une nouvelle implémentation vient apporter une modification sur un élément documenté.
Admettons : vous avez documenté une toute nouvelle feature dans le README.md après une journée de sang et de larmes, quand tout à coup, * effet dramatique *, il faut lui ajouter un nouveau comportement. Vous reprendrez bien un peu de README ?
Nous nous sommes donc penchés sur l'automatisation de cette documentation. Quel outil pourrait répondre à ce besoin ?
Un besoin de concevoir
Les pratiques crafts comme le BDD et le DDD permettent d’orienter la réflexion de développement autour du métier. Il s’agit en somme de pousser le raisonnement non pas sur les aspects techniques du développement mais bien sur la technicité du métier.
Ainsi, les comportements attendus du logiciel sont maîtrisés et l’utilisation d’outils comme le langage Gherkin fournissent une documentation fonctionnelle qui permet de s’en assurer.
Pour autant, rien ne prouve que l’architecture applicative mise en place pour correspondre aux comportements attendus représente réellement le métier qu’elle est censée adresser.
Prenons en exemple une application parfaitement fonctionnelle conçue à partir de scénarios Cucumber élaborés à la suite d’ateliers BDD. Ces scénarios attestent et documentent le fonctionnement de l’application. Pourtant, son architecture peut très bien être un agglomérat de classes et d’interfaces réparties dans des packages sans logique apparente, ou découpés de manière technique (les fameux packages services, controllers, common, ...).
Comment s'assurer que la découpe de l'application reflète le métier ? Et si le métier change, comment montrer que le code a évolué en ce sens ?
Candy-Doc
L’approche du Domain-Driven Design à la rescousse
La philosophie du Domain-Driven Design apporte au développeur un ensemble d’ateliers et d’outils qui lui permettent de mieux aborder la complexité du métier et notamment de l’aider à la refléter dans le code. Parmi ces outils, on retrouve des concepts d’architecture logicielle - des patterns stratégiques et tactiques - qui tentent de répondre au problème de la transcription du métier en code.
En prenant le domaine métier en tant que concept de plus haut niveau, on peut le découper en plusieurs contextes bornés (Bounded Contexts en anglais). Au sein de chaque contexte, on retrouve d’autres concepts comme les Aggregates, Value Objects, etc. qui vont aider à se rapprocher au mieux du métier qui doit être retranscrit.
C’est autour de ces patterns tactiques du DDD que la première version de Candy-Doc a vu le jour.
La mise en place de la stack technique
Dans un premier temps, il s’agissait de mettre en place les bases du projet afin de garantir le bon déroulement du développement.
Le choix de faire une première version de Candy-Doc sous forme d’un plugin Maven s’est fait principalement par la popularité de cette technologie.
Nos recherches nous ont donc menées à la création d’une classe particulière, le MOJO (Maven Plain Old Java Object). Celle-ci permet l’exécution du plugin et de notamment définir ses paramètres d’exécution.
Ensuite, afin de faciliter les phases de développement et de déploiement, nous avons mis en place un script d’intégration continue afin de garantir une non-régression de l’outil. Concrètement, à chaque commit l’ensemble des tests présents dans l’application sont lancés et la bonne compilation du projet est également vérifiée. Cela permet de s’assurer que chaque modification effectuée n’altère pas le comportement maîtrisé de Candy-Doc.
Le cœur métier de Candy-Doc : la manipulation des concepts d’architecture
Une fois les bases du plugin installées, il nous fallait désormais nous attaquer au développement du cœur métier de Candy-Doc : le méta DDD *mind blow*.
Notre démarche de développement peut se résumer comme une suite d'implémentations des concepts d'architecture du DDD.
Pour commencer, le premier concept à implémenter était le Bounded Context.
Il s’agissait de trouver une façon de le représenter dans le code afin de pouvoir l’identifier et l’extraire dans un projet qui allait être utilisé avec Candy-Doc. Le but étant de pouvoir le manipuler et le visualiser en dehors du code source, au travers d’une interface graphique par exemple.
Ainsi, après un temps de réflexion, nous avons répondu à ces problématiques de manipulation d’un concept avec les quatre phases suivantes :
- Représentation
Chaque concept du DDD est représenté par une annotation Java. - Extraction
Candy-Doc analyse le code du projet pour en extraire les classes enrichies par le vocabulaire du DDD en identifiant les annotations présentes dans le code. - Traitement
Une fois extrait, chaque concept est traité en deux temps. Dans un premier temps, on identifie les concepts en lien avec le concept traité afin de mettre en avant ses interactions. Cette représentation est le cœur de la documentation fournie par Candy-Doc. Dans un second temps, ces interactions sont analysées pour vérifier la présence ou non de potentielles anomalies d’architecture. Chaque pattern tactique du DDD a en effet ses propres règles et cette phase de traitement permet de vérifier que ces règles sont bien respectées. Par exemple, vérifier qu’un concept simple qui n’est pas censé avoir de logique comme un Value Object ne contienne pas une Domain Command. - Export
Candy-Doc passe ensuite à une phase d’export. Nous avons fait le choix d’implémenter trois exports différents pour le moment : JSON, YML et HTML. La partie HTML est générée aujourd’hui grâce à des templates Freemarker et constitue un premier glossaire visuel des concepts identifiés. Demain, cette partie sera détachée du plugin car nous envisageons à terme une interface évoluée avec notamment des fonctionnalités de recherche.
C’est à travers ce glossaire visuel que la principale valeur ajoutée de Candy-Doc prend tout son sens : il est désormais possible de mettre en avant les concepts métiers présents dans le code et de s’assurer que l’architecture mise en place respecte bien le métier.
Utilisation de Candy-Doc
Installation
Pour utiliser Candy-Doc sur un projet utilisant Maven, il suffit de configurer le pom.xml d’un projet selon cette configuration d’installation.
Les paramètres d’exécution du plugin sont pour le moment au nombre de deux et correspondent à :
packagesToScan
: les packages du projet sur lesquels on souhaite que Candy-Doc soit exécuté (ils correspondent potentiellement aux différents Bounded Contexts du projet)outputFormat
: le type de format de sortie que l’on souhaite générer
Au choix :
JSON/YAML : il est possible de récupérer les données sous un format standard en précisant JSON ou YML en paramètre
ou
HTML : dans le target, un dossier candy-doc est généré et contient le glossaire HTML correspondant au projet
Projet test
Prenons en exemple un service de pricing dans une application qui manipule des livres.
La conception de l’application a été réalisée selon la philosophie DDD et des patterns tactiques ont été utilisés dans l’architecture du code.
Préparation
Dans l’exemple ci-après, nous venons annoter 3 concepts métier : Book, EAN13 et Price. Dans notre cas, il s’agit respectivement d’un Aggregate et de 2 Value Objects. L’objet EAN13 étant un concept métier fort, nous l’avons annoté du mot clé CoreConcept.
@Aggregate(description = "A readable book")
public class Book {
@CoreConcept
@ValueObject(description = "Code of the book, defined by 13 numbers")
public class EAN13 {
@ValueObject(description = "Price of a book, in € or $")
public class Price {
Positionner les bonnes annotations sur les concepts est de la responsabilité des développeurs. Il est intéressant de noter que s’il est difficile d’annoter un concept, peut-être que celui-ci n’existe tout simplement pas, qu’il a été inventé pendant le processus de développement. Cela peut mettre en évidence des modélisations davantage techniques que métiers.
Lancement de Candy-Doc
Candy-doc se lance automatiquement à la compilation du projet. Notons qu’aujourd’hui, les annotations sont conservées au runtime. Il est prévu prochainement de les faire disparaître du code compilée, ce qui vaudra sans doute un autre article !
Le résultat
TA-DAA! Candy-Doc nous a généré un dossier du même nom dans notre target avec (selon l’outputFormat choisi dans la configuration du plugin) soit :
- un fichier au format standard JSON ou YML
Ce fichier au format standard récupère l’ensemble de l’architecture DDD du projet et peut être exploitable selon les besoins du développeur.
- une arborescence de fichiers HTML correspondant à nos concepts formant un glossaire
En ouvrant le fichier index.html dans un navigateur, nous pouvons ainsi explorer le glossaire visuel du projet en parcourant les différentes pages créées par concept.
Au sein de chaque Bounded Context (ici Library pour l’exemple), je peux voir et accéder aux différents concepts métiers de chaque contexte.
En allant sur la page dédiée au Book, je vois que c’est un Aggregate de mon projet et qu’il a des interactions avec deux autres concepts : EAN13 et Price.
Ce glossaire sert de documentation vivante et met en avant les 3 concepts métiers du contexte Library du projet : Book, EAN13 et Price.
L’avenir et la contribution
Nous avons vu dans cet article à travers notre retour d’expérience en tant que stagiaires, la naissance et l’utilisation de Candy-Doc.
Cette première version tourne autour des concepts d’architecture du DDD. À l’avenir, il est dans l’ambition de l’équipe de pouvoir découpler Candy-Doc de ce schéma d’architecture et d’offrir la possibilité de générer la documentation selon d’autres schémas comme l’architecture hexagonale ou également de permettre à l’utilisateur d’importer son propre schéma d’architecture avec ses propres règles.
Aussi, il serait intéressant de pouvoir avoir une vision plus globale d’une application en mettant en avant ses interactions avec d’autres services, d’autres applications, d’autres dépendances, d’autres produits, etc.
Pour l’heure, la première version vient d’être mise à disposition de la communauté open source et toute personne intéressée est invitée à contribuer ici (et à mettre une étoile pour la notoriété du projet ^^).
"J’aimerais contribuer à Candy-Doc mais je ne sais pas par où commencer ?"
Teste le plugin, navigue dans la documentation créée de ton projet.
Tu peux également la présenter à ta/ton PO pour faire ressortir la logique métier de ton code et valider ensemble que vous êtes raccord sur le métier.
Si tu as le moindre soupçon sur une issue, n’hésite pas à la créer (du plus simple libellé à l’issue la plus documentée sont acceptés ;) )
Tu veux aller plus loin et vraiment participer à la conception du code ? Crée ta feature dans une branche depuis dev et ouvre une PR.
Candy-Doc vient à peine de voir le jour et son potentiel est très élevé. Voici une liste non exhaustive des principales idées sur lesquelles le projet peut être amené à évoluer :
- ajouter des diagrammes interactifs permettant d’explorer les différents concepts
- gérer les concepts pour une architecture hexagonale
- rendre Candy-Doc disponible dans d’autres langages (Go par exemple) ou utilisable avec Gradle
- remonter des avertissements lorsque l’architecture mise en place ne respecte pas le schéma d’architecture cible
Stay tuned ! :)