Modéliser avec du code
Cet après-midi, je relisais le chapitre 8 du livre Domain-Driven Design, et j'ai été très intéressé par ce qui y est dit en introduction, sur la modélisation métier avec du code.
Notamment cet extrait, que je cite tel quel. Vous pouvez vous arrêter à l'extrait, et je me garderais bien de penser que je pourrais y ajouter quelque chose, mais si ça vous intéresse je me permettrai de partager pourquoi je trouve cet extrait intéressant, et mes réflexions sur quelques points plus bas.
The traditional way of explaining object analysis involves identifying nouns and verbs in the requirements documents and using them as the initial objects and methods. This explanation is recognized as an oversimplification that can be useful for teaching object modeling to beginners. The truth is, though, that initial models usually are naive and superficial, based on shallow knowledge.
For example, I once worked on a shipping application for which my initial idea of an object model involved ships and containers. Ships moved from place to place. Containers were associated and disassociated through load and unload operations. That is an accurate description of some physical shipping activities. It does not turn out to be a very useful model for shipping business software.
Eventually, after months working with shipping experts through many iterations, we evolved a quite different model. It was less obvious to a layperson, but much more relevant to the experts. It was refocused on the business of delivering cargo.
The ships were still there, but abstracted in the form of a “vessel voyage,” a particular trip scheduled for a ship, train, or other carrier. The ship itself was secondary, and could be substituted at the last minute for maintenance or a slipping schedule, while the vessel voyage went on as planned. The shipping container all but disappeared from the model. It did emerge in a cargo-handling application in a different, very complex form, but in the context of the original application, the container was an operational detail. The physical movement of the cargo took a back seat to the transfers of legal responsibility for that cargo. Less obvious objects, such as the ”bill of lading,” came to the fore.
Whenever new object modelers showed up on the project, what was their first suggestion? The missing classes: ship and container. They were smart people. They just hadn’t gone through the process of discovery.
―Domain-Dreven Design, Deep Models, p. 189-190
Je trouve cet extrait particulièrement intéressant, car il résonne beaucoup avec ce que j'observe quand j'essaie de modéliser du métier avec du code, afin de résoudre un problème concret. Il donne aussi un exemple en peu de mots qui permet de toucher du doigt en quoi c'est difficile de bien saisir les termes métier qui sont importants pour la modélisation.
Voilà quelques points qui m'ont marqué et pourquoi.
Modélisation objet, mais aussi fonctionnelle
Le premier point est qu'il parle de modélisation objet, qui était le paradigme dominant à la sortie du livre. Mais à mon avis, ce qu'il dit s'applique également à une modélisation fonctionnelle, autour de types et de fonctions sur ces types par exemple.
La compréhension du modèle évolue
The truth is, though, that initial models usually are naive and superficial, based on shallow knowledge.
Ça correspond à ce que j'ai observé, et si c'est vrai ça explique pourquoi il est si difficile de trouver le bon modèle tout de suite en début de projet. Et donc nécessairement, tout au long du projet on trouvera de meilleures modélisations, et quand c'est possible il serai important de retravailler le code pour qu'il s'adapte à ces meilleures modélisations.
On peut aussi en déduire l'importance de choisir une conception et des patterns de code qui rendent les changements faciles, ou plus réalistement, moins difficiles.
Un exemple de modélisation intuitive... mais peu utile
For example, I once worked on a shipping application for which my initial idea of an object model involved ships and containers.
L'exemple de première modélisation intuitive qu'il donne dans l'extrait me parle beaucoup : comment en effet ne pas penser que les notions de Ship et de Container seront centrales dans une application qui gère des transports maritimes ?
Mais la conclusion interroge :
It does not turn out to be a very useful model for shipping business software.
Trouver une modélisation réellement utile pour le problème
Eventually, after months working with shipping experts through many iterations, we evolved a quite different model. [...] It was refocused on the business of delivering cargo.
Je note qu'il leur a fallu plusieurs mois de travail avec des experts pour arriver à la modélisation qui convenait au problème. C'est une des raisons pour lesquelles développer un logiciel prend du temps : ce n'est pas le temps d'écrire le code, c'est le temps nécessaire à comprendre le problème de la bonne façon.
The ships were still there, but abstracted in the form of a “vessel voyage,” a particular trip scheduled for a ship, train, or other carrier. The ship itself was secondary, and could be substituted at the last minute for maintenance or a slipping schedule, while the vessel voyage went on as planned.
L'auteur donne là un exemple intéressant de la nouvelle modélisation avec la notion de voyage de navire, et un cas d'usage qui montre pourquoi cette modélisation est meilleure.
Certaines notions sont inutiles dans certains contextes...
Et ensuite il nous indique qu'une des notions qu'on aurait envie d'avoir intuitivement, la notion de Container, s'est révélée inutile dans le contexte de cette application :)
The shipping container all but disappeared from the model. [It] was an operational detail.
It did emerge in a cargo-handling application in a different, very complex form.
Mais que cette notion s'est avérée utile dans le contexte d'une autre application : si on essaie d'avoir une modélisation unique pour toutes nos applications, on risque de surcharger nos modèles, et de faire peser sur toutes nos applications les contraintes de toutes les autres.
... D'autres sont utiles et ne sont pas évidentes a priori
The physical movement of the cargo took a back seat to the transfers of legal responsibility for that cargo. Less obvious objects, such as the ”bill of lading,” came to the fore.
Les notions les plus utiles pour résoudre le problèmes ne sont pas toujours évidentes à trouver, et il sera nécessaire de passer du temps sur le problème et de faire de la place dans notre modèle, en évitant de tout modéliser au profit de ce va dans le sens du bois.
Une modélisation utile est un chemin
Whenever new object modelers showed up on the project, what was their first suggestion? The missing classes: ship and container. They were smart people. They just hadn’t gone through the process of discovery.
Pour finir et pour conclure, je note deux points ici que j'ai également observés :
- Chaque nouvelle personne dans l'équipe aura besoin de suivre le chemin qu'a suivi la modélisation pour se l'approprier
- On sera alors amenés à avoir des conversations au sein de l'équipe pour accompagner ces personnes sur le chemin
Et enfin, je me sens obligé de préciser a posteriori qu'il n'est pas question de complexifier inutilement une modélisation évidente qui répondrait très bien au problème. Ça existe également. Et quand c'est le cas, on peut se réjouir d'utiliser une modélisation évidente qui va dans le sens du bois.