Aller au contenu

Helpers

Vue d'ensemble

Le module Helpers regroupe les composants utilitaires réutilisables par l'ensemble du Domain Core.

Contrairement aux autres modules du Core, il ne représente pas un concept métier. Il fournit des briques techniques communes permettant de simplifier l'implémentation des différents composants tout en limitant la duplication de code.

Son objectif est de favoriser la cohérence de l'architecture sans devenir un répertoire générique de fonctions hétérogènes.


Pourquoi un module Helpers ?

Au fur et à mesure de l'évolution de la Platform, certains traitements deviennent communs à plusieurs composants.

Par exemple :

  • normaliser une chaîne de caractères ;
  • comparer deux valeurs de manière déterministe ;
  • manipuler une collection ;
  • construire un objet immuable ;
  • effectuer une validation générique.

Dupliquer ces traitements dans plusieurs modules compliquerait leur maintenance.

Le rôle de Helpers est donc de centraliser uniquement les fonctionnalités réellement partagées.


Position dans l'architecture

Les Helpers ne constituent pas une étape du Pipeline.

Ils sont utilisés comme des dépendances internes par les composants du Domain Core.

                Domain Core

 ┌────────────────────────────────────┐
 │                                    │
 │ Candidate                          │
 │ Resolver                           │
 │ Canonical Identity                 │
 │ Projection                         │
 │ Quality                            │
 │ Health                             │
 │ Promotions                         │
 │                                    │
 │            ▼                       │
 │          Helpers                   │
 └────────────────────────────────────┘

Ils n'ont pas vocation à être utilisés directement par le Frontend ou le Runtime.


Responsabilités

Le module peut notamment fournir :

  • des fonctions de normalisation ;
  • des utilitaires de comparaison ;
  • des manipulateurs de collections ;
  • des fonctions de validation génériques ;
  • des convertisseurs de valeurs ;
  • des constructeurs d'objets communs.

Chaque fonctionnalité doit être suffisamment générique pour être réutilisée dans plusieurs composants.


Ce qu'un Helper n'est pas

Un Helper n'est pas un raccourci permettant d'éviter une bonne conception.

En particulier, un Helper ne doit jamais contenir :

  • une règle métier ;
  • une logique propre à une verticale ;
  • une décision fonctionnelle ;
  • une dépendance vers une autre couche de l'architecture.

Dès qu'une fonction commence à manipuler un concept métier, elle doit être déplacée vers le composant approprié.


Critères de création

Avant d'ajouter un nouveau Helper, plusieurs questions doivent être posées.

Cette fonctionnalité est-elle :

  • utilisée par plusieurs composants ?
  • indépendante de tout contexte métier ?
  • suffisamment stable pour être mutualisée ?
  • compréhensible sans connaître une verticale ?

Si la réponse est non à l'une de ces questions, le code n'a probablement pas sa place dans ce module.


Invariants

Aucune connaissance métier

Le module ignore totalement les concepts fonctionnels de la Platform.

Il ne connaît pas :

  • les smartphones ;
  • les imprimantes ;
  • les appareils photo ;
  • les consoles ;
  • les jouets ;
  • les téléviseurs.

Il manipule uniquement des structures de données génériques.


Fonctions déterministes

Un Helper doit toujours produire le même résultat pour les mêmes paramètres.

Aucun comportement ne doit dépendre :

  • de l'heure ;
  • de l'environnement ;
  • de l'ordre d'exécution ;
  • d'un état interne.

Fonctions sans effet de bord

Dans la mesure du possible, les Helpers doivent être des fonctions pures.

Ils ne doivent pas :

  • modifier un état global ;
  • écrire en base de données ;
  • effectuer un appel HTTP ;
  • accéder au système de fichiers ;
  • déclencher un traitement Runtime.

Ils prennent des données en entrée et retournent un résultat.

Rien de plus.


Dépendances limitées

Les Helpers peuvent être utilisés par :

  • Candidate ;
  • Resolver ;
  • Canonical Identity ;
  • Projection ;
  • Quality ;
  • Health ;
  • Promotions ;
  • Read Services ;
  • Write Services ;
  • Vertical Modules.

En revanche, ils ne doivent dépendre d'aucun de ces composants.

La dépendance est toujours orientée dans un seul sens.


Exemples

Les fonctions suivantes constituent de bons candidats :

  • normalisation Unicode ;
  • comparaison de chaînes indépendante de la casse ;
  • manipulation de tableaux ;
  • conversion d'unités ;
  • validation de formats ;
  • création de Value Objects.

À l'inverse, les fonctions suivantes ne doivent jamais être placées dans Helpers :

  • résolution d'une identité ;
  • calcul d'un score smartphone ;
  • choix d'une famille d'appareil photo ;
  • génération d'une projection ;
  • décision métier.

Anti-patterns

Le module Helpers est souvent victime d'un anti-pattern classique : devenir un fichier Utils contenant des centaines de fonctions sans lien entre elles.

Cette approche est explicitement interdite dans la Platform.

Chaque Helper doit :

  • avoir une responsabilité clairement identifiée ;
  • être documenté ;
  • être réutilisable ;
  • rester indépendant du métier.

Lorsque plusieurs Helpers poursuivent un même objectif, ils doivent être regroupés dans un composant cohérent plutôt que dans une collection de fonctions disparates.


Évolution

Le contenu de ce module doit évoluer lentement.

Une fonctionnalité ne doit être extraite vers Helpers qu'après avoir démontré qu'elle est réellement commune à plusieurs composants.

Cette approche évite de créer un module trop abstrait ou contenant des éléments qui ne seront finalement utilisés qu'une seule fois.

Le principe est simple :

On extrait une fonctionnalité parce qu'elle est devenue générique, jamais dans l'espoir qu'elle le devienne un jour.


Principes de conception

Le module repose sur quelques principes simples :

  • privilégier les fonctions pures ;
  • éviter tout état interne ;
  • conserver des API simples ;
  • limiter les dépendances ;
  • mutualiser uniquement ce qui est réellement partagé.

En respectant ces règles, Helpers reste un véritable support du Domain Core et non un point de concentration de la complexité.


Voir aussi