Apportez de la clarté à votre monolithe avec des contextes bornés

Regardez la vidéo de cette conférence d’ElixirConf 2017 ci-dessous

Les applications monolithiques sont excellentes lorsque vous commencez à construire votre entreprise, mais avec le temps, elles deviennent difficiles à maintenir. Ces bases de code, à mesure qu’elles grandissent, deviennent facilement de Grosses boules de boue.

 Indiana Jones Rock

Lors de la construction d’applications de grande taille dans des frameworks tels que Rails, les principes de conception de la convention sur la configuration qui ont fait de Rails un tel plaisir à utiliser commencent à gêner lorsque l’application prend de l’ampleur. Vous pouvez également ressentir les mêmes douleurs si:

  • Le refactoring est difficile et fastidieux, car les méthodes et les classes dépendent de trop d’autres classes
  • Vous avez une liste toujours croissante d’objets métier difficiles à garder en tête. En fait, personne ne semble être en mesure de comprendre le système comme un ensemble cohérent
  • Changer de code dans une zone du code entraîne des effets secondaires inattendus et involontaires dans d’autres zones du code, car il est facile d’appeler des services et des objets globaux

Lors de notre dernière discussion ensemble, nous avons discuté du développement d’un Langage omniprésent avec les experts métier et votre équipe de développement pour aider votre équipe à travailler plus étroitement ensemble. Aujourd’hui, nous allons nous appuyer sur cela en introduisant de nouveaux outils de conception pilotée par domaine (DDD). Ensuite, nous introduirons une nouvelle structure de dossiers pour vos applications Rails, les préparant à un avenir dans lequel votre application sera moins couplée et plus cohérente. Commençons!

Parlons domaines

Un principe clé de DDD est que le logiciel que vous créez doit refléter de près le domaine (commercial) de l’organisation qui le construit. Ainsi, nous devons faire quelques devoirs pour comprendre le domaine d’activité de votre logiciel.

Un domaine est ce que l’entreprise fait, et le contexte de la façon dont elle le fait.

Revenons sur notre exemple Delorean de l’article précédent. Dans ce document, la société est commercialisée comme Uber pour les voyages dans le temps. Ainsi, son “domaine” (le “ce qu’il fait”) est le covoiturage dans le temps. Le domaine comprend également le “comment” de la façon dont il le fait – en associant des conducteurs qui possèdent des véhicules Delorean voyageant dans le temps avec des passagers qui souhaitent faire des voyages dans le temps.

Pour obtenir plus de nuances dans le domaine métier, DDD introduit un autre concept, appelé Sous-domaine:

Un sous-domaine représente les petits groupes ou unités de l’entreprise qui collaborent au quotidien pour atteindre les objectifs de l’entreprise.

Delorean est divisée en plusieurs équipes au sein de l’entreprise. Regardons deux d’entre eux, et voyons de quoi ils sont responsables:

Équipe de la plateforme Trip Équipe des opérations financières
Mission Concevoir et soutenir les systèmes qui acheminent les voyages et connectent les conducteurs aux passagers Gérer les systèmes impliquant des institutions financières et des processeurs de cartes de crédit
Responsabilités
  • Connecter les passagers aux conducteurs
  • Acheminer le conducteur vers sa prochaine destination
  • Avertir les passagers de l’arrivée des conducteurs
  • Alerter les conducteurs sur les nouveaux passagers
  • Traiter les paiements aux conducteurs
  • Maintenir l’historique des transactions à l’échelle du système pour l’audit
  • Créer des rapports financiers
  • Traiter les frais de carte de crédit pour les passagers

Chacun de ces deux groupes anime une responsabilité commerciale, ou sous-domaine. Nommons-les Expérience de covoiturage et Commerce électronique, respectivement.

Nous avons maintenant une illustration générale de l’entreprise et de deux de ses unités qui l’aident à fonctionner au quotidien. Le domaine et le sous-domaine sont des moyens de modéliser l’espace problématique de votre entreprise – et comment elle agit pour remplir ces rôles. Il y a de fortes chances que votre organigramme commercial reflète de près les sous-domaines de votre entreprise. Dans le monde réel, les délimitations peuvent être moins claires – les équipes peuvent être responsables de plusieurs sous-domaines qui se chevauchent.

Complétons ce diagramme avec quelques sous-domaines supplémentaires dans l’activité Delorean:

  • Sous-domaine de support client : résolution des tickets de support client arrivant par e-mail
  • sous-domaine marketing: gestion des campagnes marketing par e-mail et des codes promo marketing
  • Sous-domaine d’identité : Comment le système suit chaque utilisateur et ses informations d’identification

Contextes bornés dans l’espace solution

Ce diagramme devant nous reflète maintenant les objectifs commerciaux de l’entreprise, divisés en unités logiques qui (espérons-le) atteignent ses objectifs dans le monde réel. Maintenant, nous allons superposer les systèmes logiciels qui atteignent ces objectifs sur ce diagramme. Ces systèmes logiciels sont décrits comme des contextes bornés:

Un contexte borné est un système qui remplit les objectifs de l’entreprise dans le monde réel.

Tous nos systèmes logiciels (comme un service Web ou une application Web) qui fonctionnent comme des instances concrètes dans le Monde réel sont considérés comme des contextes bornés.

Techniquement parlant, le Contexte borné dans DDD-speak est une limite spécifique dans votre domaine que votre Glossaire de votre Langage omniprésent ne peut appliquer – l’idée étant que différents Sous-domaines peuvent avoir des définitions de termes concurrentes ou contradictoires. Cet article ne détaillera pas les nuances linguistiques du contexte borné. Pour en savoir plus, voir l’explication de Martin Fowler sur les contextes bornés.

Maintenant, il se trouve que chez Delorean, tous ces sous-domaines sont implémentés dans un seul système – une Grosse Boule de Rails de boue Monolithe. Nous allons dessiner une boîte bleue autour des sous-domaines dont les fonctions sont implémentées par le système logiciel. Dans ce cas, nous commencerons par notre monolithe de Rails susmentionné:

Comme c’est le monolithe, il fait fondamentalement tout – et donc ici, il mange tous les autres sous-domaines du diagramme.

N’oublions pas – nous avons quelques autres systèmes logiciels que nous n’avons pas modélisés ici. Qu’en est-il de toutes les intégrations tierces que l’entreprise utilise? Ce sont aussi des systèmes logiciels. Nous les dessinerons comme des boîtes bleues.

En passant – ce que nous avons dessiné ici est une carte de contexte – un diagramme qui mélange les objectifs commerciaux et les implémentations concrètes de systèmes logiciels. Il est utile pour évaluer la configuration de vos systèmes logiciels et visualiser les dépendances entre les équipes.

Maintenant, c’est raisonnable et propre, mais nous vivons dans le monde réel, et les logiciels du monde réel semblent rarement cohérents et cohérents. Si vous avez créé votre application Rails en suivant ses conventions prêtes à l’emploi, votre application ne dispose pas en interne des regroupements nécessaires pour visualiser votre application dans ses composants constitutifs. En réalité, la base de code Delorean ressemble plus à ceci:

Le fait est que Rails n’impose aucune contrainte organisationnelle à nos systèmes logiciels – ce qui signifie que les unités commerciales logiques (nos sous–domaines) qui suggèrent des interfaces découplées – ne sont pas matérialisées dans le code, ce qui entraîne une confusion et une complexité croissante au fil des années.

La grande idée: Organiser le code Rails en modules par sous-domaine métier

Même si vos classes Ruby de votre application vivent probablement dans l’espace de noms global, elles peuvent facilement être regroupées en modules. Notre objectif est de créer des groupes logiques de code de domaine qui peuvent être isolés en composants autonomes.

En effet, l’un des objectifs des Conceptions pilotées par domaine est d’avoir un mappage un à un d’un Sous-domaine à un Contexte borné.

OK, qu’est-ce que cela signifie? Entrons dans quelques recommandations, ainsi que des exemples.

Inverser les structures de dossiers en un regroupement plat orienté domaine

Vous vous souvenez peut-être que les conventions Rails suivantes nous conduisent à des hiérarchies de dossiers qui regroupent les classes par rôles :

Déplaçons tout vers une nouvelle structure de répertoires: regroupons plutôt les fonctionnalités par domaine. Nous allons commencer par une première variante, que j’appellerai un regroupement orienté domaine plat.

Moduliser les classes

Ensuite, vous voudrez moduler les classes de ce qu’elles étaient auparavant. Puisque la classe de pilote relève du domaine de covoiturage, nous l’ajouterons à un module de covoiturage :

Vous voudrez le faire pour chaque classe que vous déplacez dans la structure de répertoire plat app/domains.

Référencez les modèles associés par le nom complet de la classe

De plus, vous devrez modifier vos associations de modèles ActiveRecord pour faire référence à la classe par son chemin modularisé complet :

Tenez les contrôleurs à jour sur l’endroit où trouver leurs vues nouvellement modulisées

Vous devrez également insérer ce petit bit pour que les routes du contrôleur sachent où chercher les vues :

Voici la chose cool: vous n’avez pas à déplacer tout votre code à la fois. Vous pouvez choisir un petit domaine dans votre application, la zone la plus mature de votre code ou la zone que vous comprenez le mieux, et commencer à déplacer ses préoccupations dans un dossier de domaine unique, tout en laissant le code existant au repos jusqu’à ce qu’il soit prêt à se déplacer.

Maintenant, nous avons fait quelques petites étapes pour obtenir une clarté architecturale dans notre application. Si nous regardons maintenant, nos structures de dossiers modulaires nous ont aidés à regrouper notre code comme suit:

Sous le capot, notre application pourrait ressembler davantage à ceci:

Qu’est-ce qui fonctionne bien avec cette approche?

  1. Il y a moins de bruit dans chaque répertoire de fichiers – en regroupant comme des fichiers par spécificité de domaine, nous trouvons un point d’organisation naturel
  2. Les entités qui restent dans chaque dossier de domaine sont très cohésives – elles ont très probablement naturellement tendance à communiquer entre elles et à apparaître naturellement les unes avec les autres
  3. Les entités qui n’appartiennent pas ensemble sont maintenant séparées (couplées de manière plus lâche)
  4. Si vous avez les équipes qui travaillent selon des responsabilités de sous–domaine, ces ingénieurs peuvent désormais travailler de manière plus rationalisée et isolée. Un couplage plus lâche permet à ces équipes d’apporter des modifications avec la certitude qu’elles n’introduiront pas de régressions ou ne fusionneront pas les conflits dans la base de code
  5. La scène est maintenant réglée à long terme pour commencer à déplacer chacun de ces dossiers de domaine dans un service logiciel indépendant (plus d’informations à ce sujet dans un futur article de blog)

Si vous souhaitez obtenir des conseils supplémentaires sur cette structure de dossiers, j’ai développé un exemple d’application qui présente cette structure de dossiers orientée domaine: http://github.com/andrewhao/delorean. Jetez un coup d’œil et faites-moi savoir ce que vous en pensez.

Qu’avons-nous appris ?

Pendant notre temps ensemble, nous avons appris des concepts de conception pilotés par domaine autour des Domaines et des sous-domaines. Nous avons appris à visualiser nos systèmes logiciels comme des Contextes bornés sur une Carte de contexte, qui nous a montré les zones du système qui appartiennent ensemble en tant que parties cohérentes.

Pour terminer sur une note pratique, nous avons illustré comment les fichiers et dossiers Rails pouvaient être “inversés” et réinventés en tant que groupes de domaine d’abord.

Dans mon prochain article, nous poursuivrons notre discussion dans un prochain article de blog sur la façon de découpler davantage notre code Rails orienté domaine avec des événements de domaine, et de nous frayer un chemin dans le pays des microservices.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.