Clean Architecture : Les règles métiers avant tout !
Avec ce troisième article sur la Clean Architecture, rentrons un peu plus dans les détails ! Nous avons eu un premier article qui présentait de façon globale ce qu’est la Clean Architecture, puis un deuxième sur la séparation Core (code métier) vs Infrastructure (code technique). Nous allons aborder dans cet article la partie Core, et donc les règles métiers, son rôle central dans la conception et donc comme élément essentiel (principal !) de la Clean Architecture.
Comportement évident de l’application !
Ca semble en effet évident de le dire : Les règles métiers, les features, sont ce qui régissent le comportement d’une application, et donc la conception. Et pourtant… Bon nombre d’applications se retrouvent contraintes par l’aspect technique qui prime, ou empêche une règle d’évoluer.
Et c’est exactement pour ça que j’apprécie la Clean Architecture : On remet simplement des bases, qui existaient il y a des années. Elle reconnait donc la valeur des règles métiers et les met en avant. Elles ne sont pas seulement des lignes de code, mais les piliers sur lesquels repose la structure de la conception.
Plongeons dans les fondements et examinons comment elle garantit que les règles métiers priment avant tout.
Les règles métiers : Fondements de l’application
Les règles métiers représentent l’essence même de ce que fait une application. Elles définissent comment les données doivent être manipulées, quelles actions peuvent être effectuées et dans quelles circonstances. En bref, ce sont les règles du jeu qui dictent le comportement de l’application dans toutes les situations possibles.
Et elles doivent directement influencer la manière dont une application est conçue et implémentée. Elles doivent donc tout simplement guider les décisions architecturales et structurelles prises tout au long du développement.
Les Entités : Porteuses des règles métiers
Au cœur de la Clean Architecture se trouvent un ensemble d’entités, les acteurs principaux qui incarnent d’un point de vu code les règles métiers de l’application. Elles encapsulent les données et la logique métier essentielle. Si on reprend notre thématique de la pièce de théatre du précédent article, les entités seraient les protagonistes, qui portent sur leurs épaules le poids des décisions et des actions.
- Rôle des Entités : Les entités représentent les objets fondamentaux du domaine métier, tels que les utilisateurs, les produits ou les commandes. Elles capturent les règles métiers spécifiques à ces objets et veillent à ce qu’elles soient respectées à tout moment à cet unique endroit dans la code base.
- Indépendance des Entités : Les entités maintiennent une indépendance stricte vis-à-vis des détails techniques. Elles restent concentrées sur leur responsabilité principale : représenter fidèlement le domaine métier, c’est tout ! Cette indépendance permet aux entités d’évoluer indépendamment de l’infrastructure sous-jacente, ce qui garantit ainsi leur réutilisabilité et leur extensibilité
Voyons un exemple de code avec Typescript d’une Entité :
export class ExistingUser extends User {
private _id: string;
constructor({ id }: ExistingUserConstructorArgs) {
super();
this._id = id;
}
public signAndEncodeUserAccessToken() {
const accessToken = sign({ sub: this._id }, this.config.secret, {
expiresIn: 86400, // 24 hours
});
return accessToken;
}
public get id() {
return this._id;
}
}
Cette entité qui représente un utilisateur de l’application, comprend une donnée qui est son identifiant (id), et une méthode ou une règle métier, qui est la génération d’un jeton d’accès.
Les Cas d’Utilisation : Exécuteurs des règles métiers
Tout comme les entités représentent les objets centraux du domaine métier, les cas d’utilisation dirigent l’exécution des règles en coordonnant les interactions entre les différents acteurs de l’application, un maitre de cérémonie en soit !
- Rôle des Cas d’Utilisation : Les cas d’utilisation agissent comme des scénaristes, définissant les actions que les utilisateurs peuvent effectuer et les réponses que l’application doit fournir en retour. Ils traduisent les exigences métier en actions concrètes.
- Coordination avec les Entités : Dans l’exécution des cas d’utilisation, les entités fournissent les données nécessaires pour répondre aux besoins métiers spécifiques définis par chaque cas d’utilisation. Dans notre théâtre, c’est la coordination entre nos protagonistes et les texte du scénario global de la pièce, notre application.
Voyons un nouvel exemple côté code, pour un Cas d’Utilisation :
async execute(
login: string,
password: string,
): Promise<{ accessToken: string } | 'USER_NOT_FOUND'> {
this.logger.debug('[Get-user usecase] Start');
const notExistingUser = new NotExistingUser();
const user = await this.userRepository.findByLoginAndPassword(
login,
notExistingUser.hashPassword(password),
);
return user
? { accessToken: user.signAndEncodeUserAccessToken() }
: 'USER_NOT_FOUND';
}
On retrouve une méthode d’exécution, qui représente notre scénario. Que fait ce scénario ? Il va se servir d’une méthode pour récupérer un utilisateur au niveau de la base de données, et des Entités user pour utiliser des méthodes métiers, comme la génération d’un jeton d’accès vu plus haut.
Alignement avec la Clean Architecture
La Clean Architecture reconnaît l’importance des règles métiers dans la conception d’applications. Elle met ces règles au premier plan de la conception, et elle permet de garantir que chaque choix de développement est aligné sur les besoins métier de l’application
Modularité et évolutivité des Entités et des Cas d’Utilisation
Toute la logique métier de l’application repose sur les entités et les cas d’utilisation. Conçus de manière modulaire et évolutive, ils offrent une base solide pour le développement.
Modularité : Les entités et les cas d’utilisation sont conçus de manière à être facilement modifiables et extensibles. Cette modularité permet d’ajouter de nouvelles fonctionnalités ou de modifier les existantes sans compromettre l’intégrité de l’application.
Évolutivité : Les entités et les cas d’utilisation sont également conçus pour évoluer avec les besoins changeants de l’application. Par exemple, l’ajout d’une nouvelle règle métier peut être facilement intégré sans perturber les parties déjà existantes de l’application.
Robustesse et scalabilité
Cette conception modulaire et évolutive des entités et des cas d’utilisation conduit naturellement à une plus grande robustesse et à une meilleure scalabilité de l’application.
Robustesse : Comme la logique métier est isolée du reste de l’application, la Clean Architecture garantit que les règles métiers soient appliquées de manière cohérente et fiable. Cela réduit les risques d’erreurs et de bugs.
Scalabilité : Modularité et évolutivité, et donc adaptation à une croissance future de fonctionnalités ou autres développement. La Clean Architecture offre une base solide sur laquelle construire et étendre l’application au fil du temps.
Maintien de l’alignement avec les besoins métiers
En gardant toujours les yeux rivés sur les besoins métiers, la Clean Architecture assure que le développement de l’application reste en phase avec ceux-ci. Cette approche permet de s’assurer que chaque fonctionnalité développée répond directement à un besoin métier spécifique, ce qui garantit la pertinence et la valeur ajoutée de l’application.
Un article de Nicolas Lapointe.
Cet article est une introduction à la Clean Architecture, et fait partie d’une série dédiée sur ce sujet. Rendez-vous sur les prochains !
Articles sur la Clean Architecture :