D'un point de vue architectural, une couche d'abstraction de base de données, comme Entity Framework de Microsoft, annule-t-elle la nécessité d'une couche d'accès aux données distincte?

11

La façon dont c'était

Depuis des années, j'organise mes solutions logicielles en tant que telles:

  • Couche d'accès aux données (DAL) pour résumer l'activité d'accès aux données
  • Business Logic Layer (BLL) pour appliquer des règles métier aux ensembles de données, gérer l'authentification, etc.
  • Utilitaires (Util) qui n'est qu'une bibliothèque de méthodes utilitaires communes que j'ai construites au fil du temps.
  • Couche de présentation qui pourrait bien sûr être Web, bureau, mobile, peu importe.

La façon dont c'est maintenant

Depuis environ quatre ans, j'utilise Entity Framework de Microsoft (je suis principalement un développeur .NET) et je trouve que le fait d'avoir le DAL devient plus lourd que propre en raison du fait que Entity Framework a déjà fait le travail que mon DAL faisait: il fait abstraction de l’exécution de CRUD sur une base de données.

Donc, je me retrouve généralement avec un DAL qui a une collection de méthodes comme celle-ci:

public static IQueryable<SomeObject> GetObjects(){
    var db = new myDatabaseContext();
    return db.SomeObjectTable;
}

Ensuite, dans le BLL, cette méthode est utilisée comme telle:

public static List<SomeObject> GetMyObjects(int myId){
    return DAL.GetObjects.Where(ob => op.accountId == myId).ToList();
}

C'est un exemple simple, bien sûr, car le BLL aurait généralement plusieurs lignes de logique supplémentaires appliquées, mais il semble juste un peu excessif de maintenir un DAL pour une portée aussi limitée.

Ne serait-il pas préférable d'abandonner simplement le DAL et d'écrire simplement mes méthodes BLL comme telles:

public static List<SomeObject> GetMyObjects(int myId){
    var db = new myDatabaseContext();
    return db.SomeObjectTable.Where(ob => op.accountId == myId).ToList();
}

J'envisage de supprimer le DAL de futurs projets pour les raisons indiquées ci-dessus mais, avant de le faire, je voulais interroger la communauté ici pour votre recul / prévoyance / opinions avant de me lancer sur un projet et de découvrir un problème que je n'ai pas rencontré '' t anticiper.

Toutes les pensées sont appréciées.

Mise à jour

Le consensus semble être qu'un DAL distinct n'est pas nécessaire mais (faire ma propre inférence ici) est une bonne idée pour éviter le verrouillage du fournisseur. Par exemple, si j'ai un DAL qui résume les appels EF comme illustré ci-dessus, si je jamais passer à un autre fournisseur, je n'ai pas besoin de réécrire mon BLL. Seules les requêtes de base dans le DAL devraient être réécrites. Cela dit, j'ai du mal à envisager un scénario dans lequel cela se produirait. Je peux déjà faire un modèle EF d'une base de données Oracle, MSSQL est une donnée, je suis presque sûr que MySql est également possible (??), donc je ne sais pas si le code supplémentaire accordera jamais un retour sur investissement intéressant.

Matt Cashatt
la source
3
Quelle est la différence entre une couche d'accès à vos données et EF? EF n'est-il pas une couche d'accès aux données? La seule raison que je peux voir pour garder votre propre abstraction entre votre logique métier et EF est de faciliter le stubbing pour les tests et d'éviter le blocage des fournisseurs.
Marjan Venema
2
C'est mon point - il n'y a pas de différence à mon avis, mais je cherche des contre-points. Merci.
Matt Cashatt
3
Personnellement, je ne vois aucune raison de créer un DAL distinct, car EF / NHibernate sont des couches d'accès aux données en elles-mêmes. Comme Marjan l'a mentionné, avec EF, vous pouvez envisager si vous pouvez voir le fournisseur de base de données changer, dans NHibernate, vous pouvez échanger les pilotes dans une seule ligne de code (même le pilote SQLite pour les tests en mémoire), ce serait donc (IMO) du code inutile.
Patryk Ćwiek
3
Pas besoin d'avoir deux DAL. Comme d'autres l'ont indiqué, conservez votre BLL, mais veillez à ne pas verrouiller votre BLL dans des constructions spécifiques au fournisseur. J'aime toujours voir les choses descendre au niveau chaîne ou entier. Ensuite, je sais que je pourrais facilement exposer toute la jonction BLL / DAL sur un canal très primitif comme les services Web, le port série, la liaison télégraphique, je plaisante.
Andyz Smith
1
re Mise à jour: cette couche supplémentaire peut rendre les Unittests du busineslayer beaucoup plus faciles car se moquer / écraser / truquer GetMyObjects(int myId)est plus facile que se moquer / écraser / truquer GetObjects.Where(ob => op.accountId == myId).ToList().
k3b

Réponses:

6

Je ne sais pas si c'est la réponse que vous cherchez .. mais c'est parti.

Nous le faisons pour garder les choses séparées / organisées. Oui, EF / NHibernate sont des accès aux données .. mais nous limitons son utilisation à son propre assemblage avec une configuration de référentiel générique. Cet assemblage contient également tous nos mappages NHibernate, la fabrique de sessions, le code pour gérer plusieurs bases de données, etc.

Nous l'appelons toujours la «couche d'accès aux données», car l'assemblage complet existe pour prendre en charge notre ORM.

Je devrais probablement noter que notre application principale fait référence à 5 bases de données, a environ 4 à 500 objets / mappages de domaine et divers schémas. Cette configuration est donc logique pour nous. Peut-être que pour une application plus petite, vous sauteriez cet assemblage mais .. Je suis un fanatique du code organisé et le ferais probablement de toute façon :)

Simon Whitehead
la source
2

Je considère l'EF et le DAL comme des composants distincts dans un système d'entreprise. La couche d'accès aux données est une abstraction que d'autres services utilisent pour effectuer la persistance et la gestion des données. En général, Entity Frameworks crée une belle API autour de l'interrogation, de la mise à jour, de la suppression et de l'insertion, mais au fond, ils nécessitent toujours une connexion directe à la source de données principale. Ainsi, tout type de routage ou de pare-feu empêchera l'EF de fonctionner, vous obligeant ainsi à créer un composant de médiation EF.

Voici un exemple de haut niveau montrant où DAL et EF s'intègrent:

-------------    -------                                    ----------------    ------
| Service A | -> | DAL | -> { LOCAL / LAN / WAN ACCESS } -> | DAL BACK-END | -> | EF |
-------------    -------                                    ----------------    ------

D'après mon expérience, une meilleure conception consiste à ne jamais permettre à la logique métier ou aux implémentations de service d'accéder directement à la couche EF. Au lieu de cela, pour fournir une abstraction pour travailler avec toutes les données persistantes qui vous permet d'envoyer des demandes sur le câble ou de les exécuter localement.

Cette conception introduit cependant quelques abstractions qui fuient. Il faut donc le considérer au cas par cas.

Quelques questions à se poser:

  • Tous les composants accédant à vos données pourront-ils obtenir une connexion au magasin de données principal?
  • Votre EF vous permet-il d'agréger des ensembles de données sur différents types de magasins de données? Par exemple, utiliser une base de données SQL avec MongoDB pour les documents.
Andrew T Finnell
la source
1

De nos jours, la question de savoir si vous allez ou non modifier le stockage des données est plus intéressante qu'elle ne l'était auparavant, car la question n'est peut-être pas simplement de savoir si vous souhaitez ou non permuter entre MS SQL ou Oracle SQL, mais la plus grande question de savoir si vous peut utiliser l'une des différentes offres de stockage de données NoSQL comme référentiel de données.

S'il y avait une possibilité sérieuse de ce type de changement, il pourrait être utile de garder votre code EF isolé dans votre DAL afin que vous puissiez introduire un nouveau DAL à l'avenir qui mapperait vos demandes de référentiel à une base de données NoSQL. Il se peut qu'un tel changement se traduise de toute façon par une réécriture complète de votre BLL en raison d'hypothèses liées à la base de données qui se glissent naturellement.

De même, EF dans un DAL rendrait probablement plus simple la simulation de l'accès aux données pour vos tests unitaires de code BLL.

Mon avis est donc que EF (ou d'autres ORMS) n'annule pas nécessairement la nécessité d'une couche d'accès aux données.

Alex White
la source