Hablando arquitectónicamente, ¿una capa de abstracción de base de datos, como Entity Framework de Microsoft, anula la necesidad de una capa de acceso a datos separada?


11

De la forma que era

Durante años, he organizado mis soluciones de software como tales:

  • Capa de acceso a datos (DAL) para abstraer el negocio de acceder a datos
  • Business Logic Layer (BLL) para aplicar reglas comerciales a conjuntos de datos, manejar autenticación, etc.
  • Utilidades (Util), que es solo una biblioteca de métodos de utilidad comunes que he construido con el tiempo.
  • Capa de presentación que, por supuesto, podría ser web, escritorio, móvil, lo que sea.

Como es ahora

Durante los últimos cuatro años más o menos, he estado usando Entity Framework de Microsoft (soy predominantemente un desarrollador de .NET) y descubrí que tener el DAL se está volviendo más engorroso que limpio debido al hecho de que Entity Framework ya ha hecho el trabajo que solía hacer mi DAL: abstrae el negocio de ejecutar CRUD en una base de datos.

Entonces, generalmente termino con un DAL que tiene una colección de métodos como este:

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

Luego, en el BLL, este método se usa como tal:

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

Este es un ejemplo simple, por supuesto, ya que el BLL normalmente tendría varias líneas lógicas más aplicadas, pero parece un poco excesivo mantener un DAL para un alcance tan limitado.

¿No sería mejor simplemente abandonar el DAL y simplemente escribir mis métodos BLL como tales:

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

Estoy considerando dejar el DAL de futuros proyectos por las razones indicadas anteriormente, pero antes de hacerlo, quería encuestar a la comunidad aquí por su retrospectiva / previsión / opiniones antes de comenzar un proyecto y descubrir un problema que no conocí. No anticipo.

Cualquier pensamiento es apreciado.

Actualizar

El consenso parece ser que no es necesario un DAL por separado, pero (haciendo mi propia inferencia aquí) es una buena idea evitar el bloqueo del proveedor. Por ejemplo, si tengo un DAL que está abstrayendo las llamadas EF como se ilustra arriba, si alguna vez cambie a otro proveedor. No necesito reescribir mi BLL. Solo esas consultas básicas en el DAL tendrían que reescribirse. Dicho esto, me resulta difícil imaginar un escenario en el que esto suceda. Ya puedo hacer un modelo EF de una base de datos Oracle, MSSQL es un hecho, estoy bastante seguro de que MySql también es posible (??), así que no estoy seguro de si el código adicional otorgaría un ROI que valga la pena.


3
¿Cómo es una / su capa de acceso a datos diferente de EF? ¿No es EF una capa de acceso a datos? Únicas razones que puedo ver para mantener su propia abstracción en medio de su lógica de negocio y EF es hacer tropezar más fácil para probar y para evitar el bloqueo de proveedor en.
Marjan Venema

2
Ese es mi punto: no hay diferencia en mi opinión, pero estoy buscando contrapuntos. Gracias.
Matt Cashatt

3
Personalmente, no veo ninguna razón para crear un DAL separado, porque EF / NHibernate son capas de acceso a datos en sí mismas. Como mencionó Marjan, con EF puede considerarlo si puede ver el cambio del proveedor de la base de datos, en NHibernate puede intercambiar controladores en una línea de código (incluso controlador SQLite para pruebas en memoria), por lo que sería un código innecesario (IMO).
Patryk Ćwiek

3
No es necesario tener dos DAL. Como han dicho otros, mantenga su BLL, pero tenga cuidado de evitar bloquear su BLL en construcciones específicas del proveedor. Siempre me gusta ver que las cosas lleguen al nivel de cadena o entero. Entonces sé que podría exponer fácilmente toda la unión BLL / DAL a través de un canal muy primitivo como servicios web, puerto serie, enlace de telégrafo, es broma.
Andyz Smith

1
Actualización: esta capa adicional puede hacer que Unittests del busineslayer sea mucho más fácil porque burlarse / tropezarse / falsificarse GetMyObjects(int myId)es más fácil que burlarse / tropezarse / falsificarse GetObjects.Where(ob => op.accountId == myId).ToList().
k3b

Respuestas:


6

No estoy seguro si esta es la respuesta que estás buscando ... pero aquí va.

Lo hacemos para mantener las cosas separadas / organizadas. Sí, EF / NHibernate son acceso a datos ... pero limitamos su uso a su propio ensamblado con una configuración genérica de repositorio. Este ensamblaje también contiene todas nuestras asignaciones de NHibernate, Fábrica de sesiones, código para manejar múltiples bases de datos, etc.

Todavía nos referimos a ella como la "Capa de acceso a datos", porque todo el conjunto existe para admitir nuestro ORM.

Probablemente debería tener en cuenta que nuestra aplicación principal hace referencia a 5 bases de datos, tiene aproximadamente 4-500 objetos de dominio / mapeos y varios esquemas. Entonces, esta configuración tiene sentido para nosotros. Quizás para una aplicación más pequeña omitiría este ensamblaje, pero ... Soy un fanático del código organizado y probablemente lo haría de todos modos :)


2

Veo el EF y el DAL como componentes separados en un sistema Enterprise. La capa de acceso a datos es una abstracción que otros servicios usan para realizar la persistencia y gestión de datos. Por lo general, Entity Frameworks crea una buena API en torno a las consultas, la actualización, la eliminación y la inserción; sin embargo, en el núcleo todavía requieren una conexión directa con la fuente de datos de fondo. Por lo tanto, cualquier tipo de enrutamiento o cortafuegos impedirá que el EF funcione, lo que requerirá que cree un componente de mediación EF.

Aquí hay un ejemplo de alto nivel que muestra dónde encajan DAL y EF:

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

Según mi experiencia, un mejor diseño es nunca permitir que la lógica de negocios o las implementaciones de servicios tengan acceso directo a la capa EF. En cambio, para proporcionar una abstracción para trabajar con todos los datos persistentes que le permite enviar solicitudes por cable o realizarlas localmente.

Sin embargo, este diseño introduce algunas abstracciones con fugas. Por lo tanto, debe considerarse caso por caso.

Algunas preguntas para hacer:

  • ¿Todos los componentes que acceden a sus datos podrán obtener una conexión al almacén de datos de fondo?
  • ¿Su EF le permite agregar conjuntos de datos en diferentes tipos de almacenes de datos? Por ejemplo, usando una base de datos SQL con MongoDB para documentos.

1

Hoy en día, la pregunta de si va a cambiar o no el almacenamiento de datos es más interesante de lo que solía ser, ya que la pregunta podría no ser solo si cambiaría o no entre MS SQL u Oracle SQL, sino la pregunta más importante de si podría utilizar una de las diversas ofertas de almacenamiento de datos NoSQL como su repositorio de datos.

Si existiera una posibilidad seria de ese tipo de cambio, podría ser valioso mantener su código EF aislado dentro de su DAL para que pudiera introducir un nuevo DAL en el futuro que asignara sus solicitudes de repositorio a una base de datos NoSQL. Es posible que dicho cambio termine con una reescritura general de su BLL de todos modos debido a los supuestos relacionados con db que se arrastran, por supuesto.

Del mismo modo, EF dentro de un DAL probablemente haría que la burla del acceso a datos para sus pruebas de unidad de código BLL sea más sencilla.

Entonces, mi opinión es que EF (u otros ORMS) no anula necesariamente la necesidad de una capa de acceso a datos.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.