La grande majorité des projets Web .Net sur lesquels j’ai pu travailler sont tous plus ou moins structurés de la même manière. Pour faire simple : une couche Web qui référence une couche Business ou applicative, qui elle-même référence un projet d’accès aux données (DAL).

Qui parmi vous n’a pas déjà travaillé sur un projet structuré comme ça ?

S1

Eh bien non ! A mon avis, le projet Business ne devrait pas référencer la DAL, mais plutôt l’inverse :


S2

Voici quelques lignes sur une simple inversion de flèche…

Pourquoi ?

Lorsqu’un projet en référence un autre, il dépend de celui-ci. Une couche Business contient la logique métier. A la question « ma logique métier dépend-elle de ma logique de persistance ? », la réponse devrait être non, c’est la logique de persistance qui dépend de la logique métier.

Le but d’une architecture N-Tiers est de réduire le couplage entre les différentes composantes de l’application. Cette inversion de dépendance participe à ce découplage car sans elle, l’application est pieds et poings liés à la base de données.

Certains pensent qu’il faut au contraire rendre la Dal indépendante car elle pourrait être utilisée par d’autres applications. Si on suit les principes du DDD, on préférera rendre la couche Business indépendante car c’est la logique métier qui est la plus susceptible d’évoluer. Garder ce code sans « bruit » lié à de l’infrastructure permet des modifications beaucoup plus simples à mettre en place.

C’est le principe d’inversion de dépendance : les couches de plus haut niveau (BL) ne doivent pas être couplées à des couches de plus bas niveau (DAL).

Concrètement, qu’est ce que ça change ?

Cette inversion de dépendance ne parait pas indispensable à première vue (« mon projet marche très bien comme ça »). Cependant, elle apporte des changements intéressants (voire nécessaires !) :

  • La couche BL est complètement indépendante (principe DDD), et donc réutilisable dans un autre contexte.
  • On peut changer la DAL (et donc le système de BDD) beaucoup plus facilement : pas besoin de toucher une seule ligne de code de la BL. On peut se dire qu’on ne change pas souvent de base de données, mais le besoin se fait parfois sentir.
  • Les développeurs qui codent sur la BL ne sont pas tentés de mélanger du code d’accès aux données dans de la logique Business.
  • Les objets métiers ne sont déclarés que dans la BL : pas besoin de projet « Common », ou de référencer la DAL dans tous les projets pour y avoir accès.
  • Ça ne coûte pas plus cher de bien manger !

Comment ?

Une simple interface et un peu d’injection de dépendances suffisent. La couche business déclare une interface, la DAL l’implémente, et un autre projet se charge de la construction.

Voici une proposition de solution qui montre les dépendances entre chaque projet et le détail sur comment implémenter l’inversion de dépendance:

a

 

La construction du repository est faite ici avec un Framework d’injection de dépendances, mais une factory ferait très bien l’affaire. Elle est implémentée dans un projet tierce pour éviter à l’UI de référencer la DAL, mais cela pourrait être acceptable si on ne l’utilise pas directement : cette séparation est un garde-fou.

Comme on l’a vu plus haut, la couche business est indépendante et n’est couplée à rien. On y trouvera du code compréhensible, proche du langage humain, contenant des termes métiers. Rien concernant de l’infrastructure, base de données, et logique applicative (gestion de fichiers par exemple).

Pour finir

Gardons en tête que chaque projet a ses propres contraintes, et de ce fait, doit avoir une architecture propre. La proposition faite ici peut cependant s’appliquer à beaucoup de projets, elle peut être étoffée, notamment en ajoutant une couche applicative (ou de service) entre la couche web et le domaine.

Le fait de rendre la couche business indépendante de la DAL peut bien sûr s’appliquer à tout autre projet lié à une infrastructure ou une technologie. C’est le principe de l’architecture hexagonale, la couche business peut être intégrée dans n’importe quel contexte, il suffit d’implémenter dans d’autres projets les interfaces qu’elle expose.

7 Commentaires Laisser un commentaire

merci pour cet article.
Dans ce type d’architecture, où écrirait-on les règles métiers qui d’habitude sont écrites dans la couche domain ? Je ne me vois pas trop les mettre dans la couche web. Du coup, il manque aussi une flèche entre web et dal.

Répondre
Jean DUMAS DE RAULY
Jean DUMAS DE RAULY
septembre 3, 2015 11:03

Bonjour,
Les règles métiers doivent rester dans la couche domain. Toute interaction avec la DAL passe ici par l’interface du repository. Il faut étoffer celle-ci pour répondre aux besoins de la couche Web (en écriture et en lecture)
Par exemple :


public interface ICarRepository
{
IEnumerable GetByColors(string color);
void Save(Car car):
}

Dans ce cas, il n’y a pas de référence directe entre Web et Dal.

Répondre
Jean DUMAS DE RAULY
Jean DUMAS DE RAULY
septembre 4, 2015 22:42

Thanks 🙂

Répondre
Rénald VENANT-VALERY
septembre 4, 2015 16:14

Simple et intéressant ! Les entités dans la couche métier (domain model)… je réfléchis à ce que ça peut donner si un ORM est impliqué dans la partie. Car si on pousse le concept, on doit pouvoir se retrouver avec une première définition des entités dans la BLL (nice), et une seconde définition du schéma de stockage dans la DAL via l’ORM (nice aussi, car on a bien 2 définitions qui sont clairement différentiables)… et ça, c’est très DDD !

Répondre
Jean DUMAS DE RAULY
Jean DUMAS DE RAULY
septembre 4, 2015 23:06

Merci !
En fait, avec ou sans ORM, il n’y a pas besoin de redéfinir les entités dans la couche DAL. IL suffit d’y implémenter le mapping vers la base de données. Je pense que dans la plupart des cas, cela doit suffire. Peut-être dans certains cas, si le modèle de stockage est très différent du modèle métier et que le mapping n’est pas possible, il peut être intéressant d’avoir des entités propres à la DAL ?

Répondre
Rénald VENANT-VALERY
septembre 9, 2015 16:36

Tout à fait. Ce serait d’avantage l’endroit pour utiliser un micro-ORM… Merci pour ce post, je pense que je vais implémenter cette approche dans peu de temps.

Répondre

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *