Salut, Habr.Aujourd'hui, je suis allé sur la chaîne #school dans la communauté russe
GoCommunity de Slack et
j'ai trouvé
un dialogue intéressant là-bas . Ce dialogue m'a amené à réfléchir à la façon dont mes collègues interprètent le concept de
«modèle de domaine» .
Il s'est avéré qu'il y a beaucoup d'interprétations incorrectes ou pas tout à fait exactes, et parfois complètement inexactes de ce terme, ce qui le déforme essentiellement. Autour de ce dialogue, l'idée de cet article est née. Détails sous la coupe.
Question sur l'architecture.
Ainsi, le développeur a posé la question suivante dans la communauté:
Dites-moi comment faire l'architecture correctement, disons que j'ai créé une tablette dans la base de données, demandé des réformes pour générer un modèle pour moi, puis-je utiliser ce modèle comme modèle de domaine dans mon application, ou est-il préférable de créer mon propre modèle de domaine et de faire un adaptateur qui me donnera exactement mon modèle de domaine la créer à partir d'un modèle de réforme? "
À quoi un autre programmeur a donné la réponse suivante:
La plus simple est l'architecture avec un modèle anémique. c'est lorsque le modèle de base de données DB = modèle de domaine = modèle de réponse API. le modèle de domaine riche est une bête rare et dégénère généralement en anémie. Par anémique, on entend une structure DTO. l'ensemble habituel d'attributs (champs) sans méthodes. La logique dégénère en un ensemble de fonctions qui fonctionnent sur un tel dto. Fowler considère parfois qu'une telle architecture est contre-paternelle. Mais alors une bonne solution de microservice, etc.
Après avoir lu ceci, je me suis soudain rendu compte pourquoi il y avait tant de controverse autour de l'organisation de la couche logique métier, et pourquoi beaucoup de gens ne mettent pas en pratique des approches telles que l'
architecture propre , etc. Que signifie
«architecture à modèle anémique» ?
Si vous essayez de trouver un tel concept sur le réseau, vous ne le trouverez probablement pas, car il n'y a pas une telle architecture. Il y a le concept de
"AnemicDomainModel" , et si nous nous tournons vers le même Fowler, il s'avère que ce n'est qu'une
approche procédurale pour créer une architecture d'application (bonjour Fortran, ALGOL, COBOL, BASIC, Pascal et C). C'est, en substance, ce que l'auteur de la réponse appelle
«l'architecture avec un modèle anémique» .
Le modèle de domaine.
Ensuite, la question suivante se pose: le
«modèle anémique» est-il essentiellement un modèle? Je ne pense pas, et c'est pourquoi.
La vérité est que le modèle de domaine n'est pas un modèle de données, contrairement au
«modèle DB» ou au
«modèle de réponse API» . Le modèle de domaine
a une définition très spécifique . De plus, il est faux d'interférer avec le modèle de base de données, qui est essentiellement un
modèle de données .
En ce qui concerne le modèle de domaine, c'est précisément le modèle conceptuel. Et c'est la totalité des concepts du domaine et les relations entre eux (c'est-à-dire la totalité des comportements et des données). En général, la principale caractéristique qui distingue un modèle d'un domaine d'un autre est précisément un ensemble de règles commerciales.
Oui, le modèle conceptuel peut fonctionner avec des données présentées sous différentes formes (données de la base de données ou réponses de l'API), mais l'essence de cela ne changera pas, le
comportement est primordial . Nous passons l'entrée au modèle pour obtenir une sortie spécifique. Ce résultat est obtenu en implémentant la logique métier dans le modèle (en d'autres termes, en appliquant des règles métier). Je trouve ici une analogie avec les modèles mathématiques et la modélisation des processus technologiques (bonjour les années étudiantes).
En quoi consiste la substitution de concepts?
Lorsque vous appelez des structures de données un
«modèle de domaine» , vous êtes libre ou non de remplacer des concepts. Cela conduit au fait que la logique métier est souvent répandue dans l'application. En fait, le modèle du domaine dans ce cas est l'ensemble de fonctions très étalé qui fonctionne avec des structures de données.
Dans le cas du développement d'applications moyennes et grandes, un malentendu ou un mélange de ces concepts, en règle générale, conduit à un certain nombre de problèmes et de questions déjà au début du développement du système, sans parler du support à long terme. Parmi eux, par exemple, il existe des questions courantes telles que:
- "- Où valider les données?"
- "- Comment éviter les dépendances cycliques?"
- "- Est-ce que" cette "logique métier en général?"
- "- Et où gardons-nous la logique métier?"
- etc.
De plus, si vous avez un CRUD simple, c'est-à-dire essentiellement une interface avec la base de données, il n'y aura probablement aucun problème. Si vous écrivez une bibliothèque au niveau de l'infrastructure (par exemple, pour travailler avec un réseau ou avec la même base de données), il ne devrait pas non plus y avoir de problème. En effet, il existe un RFC et toutes les «règles métier» sont claires depuis longtemps et la logique est claire depuis longtemps. Vous pouvez écrire un programme procédural simple et tout ira bien de toute façon.
Si nous revenons au fait que le dialogue sur les modèles de domaine a pris naissance dans la communauté Go, je dirais que oui. Étant donné que Go est un langage multi-paradigme et prend en charge un certain nombre des concepts de POO les plus réussis (Composition, Interfaces), ne les ignorez pas lors de la modélisation d'un domaine et écrivez du code exclusivement dans un style procédural, comme si vous travaillez avec BASIC ou C.
Interprétant correctement le concept de «modèle de domaine», il devient assez évident pourquoi il est souvent habituel de séparer la logique métier en une couche distincte. Il devient également clair comment vous pouvez sélectionner cette même couche et implémenter une architecture propre ou toute autre variante de celle-ci. En isolant une couche distincte, nous créons essentiellement une bibliothèque qui implémente le modèle conceptuel sous forme de code de programme. En conséquence, la logique métier devient encapsulée dans le cadre de cette bibliothèque, et n'est pas répartie dans toute l'application (comme avec une approche procédurale pure).
Bien sûr, la compréhension de ces concepts ne vous évitera pas d'erreurs de conception, ne fera pas de vous un développeur ou un architecte de systèmes idéal et ne vous apprendra pas à tout faire correctement la première fois. Ici, non seulement la théorie est importante, mais aussi la pratique. Néanmoins, dès que vous comprendrez correctement les concepts et interpréterez les définitions, beaucoup de choses deviendront beaucoup plus évidentes et plus simples pour vous.
Pour résumer.
- Il n'est pas correct d'appeler «données» un modèle de domaine.
- Un modèle de domaine est un modèle conceptuel qui inclut à la fois le comportement et les données. Il peut être encapsulé dans une couche distincte, ou il peut être réparti tout au long de l'application.
- «L'architecture avec un modèle anémique» n'est rien de plus qu'une approche procédurale pour créer une architecture d'application dans laquelle le modèle de domaine est réparti dans toute l'application
Faites attention aux définitions, étudiez-les plus profondément que la simple lecture en diagonale. Très souvent, nous sommes paresseux et saisissons des informations en morceaux, après quoi une distorsion se produit certainement. N'oubliez pas de revenir et de vous souvenir des choses qui vous paraissent évidentes depuis longtemps, et toujours vous référer aux sources et appeler un chat un chat.
Bon à tous! Merci de votre attention.
PS. Je serai heureux d'écouter les critiques constructives, ainsi que votre vision de ce qu'est un «modèle de domaine». Les références à la source sont les bienvenues.
UPD: L'article n'est pas une tentative d'interpréter librement le concept de "modèle de domaine" et de mettre dans ce concept un sens que je connais. Je veux transmettre ceci: le sens de ce concept a longtemps été investi et il est décrit en détail dans des livres et des articles sur ComputerScience. L'article est une tentative de faire comprendre aux collègues l'importance d'une perception correcte de ces mêmes concepts sans déformer leur signification (ceci est important car en pratique, il vous permettra d'écrire du code plus significatif).
UPD2: Je ne suis pas un architecte théoricien d'entreprise. Je suis le même développeur que vous. J'écris du code tous les jours et je parle de ces choses pour améliorer mon code et rendre les clients plus heureux. Si, à votre avis, j'ai déformé le sens d'origine, partagez les liens vers la source et indiquez où je l'ai mal mis, afin que je puisse le corriger.
UPD3: Parce que beaucoup interprètent le terme «domaine» de différentes manières, je donne quelques exemples de domaines afin qu'il n'y ait pas de confusion et de substitution de concepts. Le sujet dépend toujours du problème que vous résolvez en utilisant le développement d'applications:
- Réservation de billets (si vous êtes développeur de systèmes de réservation)
- Banque (si vous êtes développeur d'applications bancaires)
- Systèmes d'exploitation (si vous êtes développeur développeur de système d'exploitation)
- Gestion de l'infrastructure cloud (si vous êtes développeur k8s)
- Virtualisation (si vous êtes un développeur Docker)
- Surveillance des performances (si vous êtes un développeur Prometheus / Grafana)