Il y a 14 ans -
Temps de lecture 2 minutes
Jazoon – Jour 2 – DDD et Value Objects
En fin de matinée, nous avons eu une présentation Domain Driven Design et Value Objects (attention, ces VO là ne sont pas des DTO !). Cette présentation ne fait pas partie des révélations de Jazoon, néanmoins elle a fait preuve de bon sens, et ça on aime !
Comme la présentation, commençons par la conclusion. Evitez d’éparpiller la logique métier ou pire d’utiliser des règles de gestion implicites, utilisez notamment les Value Objects pour décrire la logique métier. Cela rend le code plus compréhensible et plus facile à tester.
Dan Bergh Johnsson a pris l’exemple d’un numero de téléphone saisi dans un formulaire et géré en backend sous forme de String. Cette String est passée en paramètre à différents services qui valident le format du numéro avant d’en extraire l’indicatif de la région (+33 pour la France). Voilà une situation courante qui présentent de nombreux défauts :
- La validation est faite dans un service (pas forcément intuitif) et a donc peu de chances d’être réutilisée
- Cela conduit souvent à une duplication de code (chaque service redéfinit sa validation) voire pire, la validation est déléguée à des classes « utilitaires »
- On créé des règles métier implicites : derrière le String se cachent de nombreuses règles métier, un format précis, un indicatif, etc
C’est là que les Value Objects viennent à notre secours. Centralisons la « logique métier » dans une classe PhoneNumber
(notre ValueObject). Cette classe possède un constructeur prenant un String en paramètre et se charge de la validation du format. Ajoutons une méthode qui extrait l’indicatif du numéro (définition du comportement, de la programmation OO tout simplement) et tout devient plus clair.
Prenons un peu de recul sur notre Value Object, et comparons le avec une validation par Service :
- API : plus besoin de chercher, les méthodes sont définies sur la classe
PhoneNumer
- Validation / gestion d’erreur : la validation est faite dans le constructeur, une fois la classe instanciée il n’y a plus de risque de mauvais format
- Compréhension métier : tout est dans une seule classe, intuitive à lire
- Testabilité : les cas à tester sont moins nombreux grâce à la validation faite à la construction
Cette présentation a réussi à aborder le DDD avec pragmatisme, en évitant le baratin habituel sur ce genre de sujets.
Commentaire
2 réponses pour " Jazoon – Jour 2 – DDD et Value Objects "
Published by Cyril Gambis , Il y a 14 ans
J’avoue que j’ai un peu de mal à comprendre l’intérêt des Value Object, du moins tels que vous les présentez: vous décrivez ni plus ni moins la troisième propriété de tous les langages orientés objet: l’encapsulation (les deux autres étant l’héritage et le polymorphisme).
L’encapsulation prône effectivement que les données et les méthodes qui agissent sur ces données (par exemple la validation, dans votre exemple) soient dans la même classe.
Hors, les architectures orientées services ont mis à mal ce design, car il est peu maintenable et incite à placer tout et n’importe quoi dans la classe (formattages, règles métiers…). Ces architectures prônent justement une séparation entre les données (on parle d’objets « POJO ») et les traitements qui s’appliquent sur ces données (réalisés dans des services bien définis).
Peut-être que votre exemple est mal choisi, mais en remettant l’encapsulation au goût du jour, on retourne 7 ans en arrière au niveau architecture…
Cyril
Published by Nicolas Le Coz , Il y a 14 ans
Bonjour Cyril,
Tu opposes le DDD et le SOA sur ce principe de design. Je ne pense pas que se soit blanc ou noir (tous les traitements dans le service ou dans l’objet). Je ne pense pas non plus qu’un POJO se résume à des attributs et des getter/setter sur ces attributs (cf le très bon livre de Chris Richardson : POJO in action : http://www.manning.com/crichardson/), preuve à l’appui de Monsieur Martin Fowler : anti pattern : anemic domain model : http://en.wikipedia.org/wiki/Anemic_Domain_Model. Un POJO peut, et parfois même, doit contenir des traitements métiers.
D’ailleurs, le DDD n’impose pas de tout mettre les traitements dans l’objet. C’est vrai que le DDD a posé comme anti-pattern le « fat service » qui sont les services où il y a trop de traitement, la aussi peu maintenable. Un objet contenant trop de traitement est aussi peu maintenable.
L’article de Guillaume parle d’un seul pattern du DDD : Value Object.
Il y a d’autres patterns dont :
– Service
– Entity
– Repository
– Specification
– Bounded Context
– …
Il faut voir ces patterns ensemble.
Un bounded context est un contexte fonctionnel d’application du domaine. Un objet Entity ou Value Object est conçu en fonction de ce contexte (dans un contexte facturation, dans un contexte reporting, …).
Voici comment doit être construit un service en DDD :
– Les opérations effectuent par le service utilisent les objets du domaine.
– Les opérations qui sont dans le service, sont des opérations qui ne sont pas naturelles de les mettre dans l’objet
– Les services sont sans état (stateless)
– Les services enrichient les traitements des Entities ou VO, traitements qui ne sont pas compris dans le bounded context
L’idée est donc de mettre les traitements propre au bounded context dans l’objet, les autres traitements dans le service.
En creusant, on remarque vite que ce n’est donc ni noir ni blanc.
Le design reste un art aidé par des techniques. Malheureusement il n’y a pas de règle précise pour savoir de manière déterminée où doit être mis un traitement. Il faut faire preuve de discernement.
Mes 2 cents,
Nicolas LC (Xebia)