java - diseño - patron dto
Pros y contras del uso del patrón DAO (8)
Como mencioné en el título, me interesa saber qué piensan ustedes (como desarrolladores experimentados) sobre el uso del patrón DAO, específicamente dentro de una aplicación web. ¿Qué ventajas ha encontrado y qué consecuencias de su uso le han disgustado?
Beneficios de usar el patrón de diseño DAO
El patrón de diseño de objetos de acceso a datos o DAO es un buen ejemplo de abstracción y encapsulación de principios orientados a objetos. Separa la lógica de persistencia es una capa separada llamada capa de acceso a datos que permite a la aplicación reaccionar de manera segura para cambiar el mecanismo de persistencia. Por ejemplo, si cambia del mecanismo de persistencia basado en archivos a la base de datos, su cambio se limitará a la capa de acceso a datos y no afectará a la capa de servicio ni a los objetos del dominio. El objeto de acceso a datos o el patrón DAO es bastante estándar en la aplicación Java, ya que es el núcleo Java, la aplicación web o la aplicación empresarial. Los siguientes son algunos de los beneficios de usar el patrón DAO en la aplicación Java:
El patrón de diseño DAO también mantiene el acoplamiento bajo entre las diferentes partes de una aplicación. Al utilizar el patrón de diseño DAO, su capa de vista es completamente independiente de la capa DAO y solo la capa de servicio tiene la dependencia, que también se abstrae mediante el uso de la interfaz DAO.
El patrón de diseño DAO permite que la prueba JUnit se ejecute más rápido, ya que permite crear simulacros y evitar conectarse a la base de datos para ejecutar pruebas. Mejora las pruebas porque es fácil escribir pruebas con objetos simulados, en lugar de una prueba de integración con la base de datos. En el caso de cualquier problema, mientras se ejecuta la prueba unitaria, solo necesita verificar el código y no la base de datos. También escudos con conectividad de base de datos y problemas de entorno.
Dado que el patrón DAO se basa en la interfaz, también promueve el principio de diseño orientado a objetos "programación para interfaz más que implementación", lo que da como resultado un código flexible y de calidad.
NOTA: es posible que encuentre otras deficiencias, pero aquí hay una lista rápida de mi experiencia
PROS:
- Llamadas comunes para recuperar objetos.
- Una vez que tenga el conjunto general de flujo crear / leer / actualizar / eliminar, el diseño general se puede repetir para otros DAO.
- También se consolida donde la parte específica de persistencia de su código puede ir. Separa la lógica de negocios de otros componentes de su código.
CONTRAS:
- No es la cosa más flexible nunca.
- Si desea cargar de forma perezosa algunos objetos secundarios, tendrá que mezclar los DAO con otras capas o tomar precauciones cuando intente recuperar los objetos perezosos.
- Si escribe a mano los DAO, entonces el código puede volverse tedioso y repetitivo.
¿Qué alternativa estás considerando?
Parece bastante obvio que colocar la responsabilidad por la persistencia en otro lugar que no sea el nivel de presentación generalmente será bueno, solo por los argumentos de claridad de responsabilidad y reutilización. Instintivamente opto por un enfoque de tres capas: Presentación, Servicio, Persistencia. Confieso haber estado haciéndolo de esta manera durante tanto tiempo que no puedo aducir pruebas de dolor sufrido por no hacerlo de esa manera. A mí me parece "obvio" que tener una sola capa que comprenda el mecanismo de persistencia debe simplificar las pruebas, facilitar el mantenimiento y proporcionar una buena separación de preocupaciones.
Así que eso deja la pregunta de cómo hacer exactamente la capa de persistencia. Mi suposición predeterminada sería utilizar JPA (o marcos similares). Veo esto como un ejemplo sofisticado de DAO.
Entonces veo dos costos de DAO. Primero necesitas invertir en la estructura de tu programa, su diseño. Para casos triviales esto puede parecer una exageración. En segundo lugar, si utiliza un marco que implementa DAO, hay una curva de aprendizaje. Comparado con solo escribir el código JDBC directamente, esta es otra inversión.
Hemos visto algunos beneficios reales al introducir un patrón DAO en nuestra implementación. Esto se debe principalmente a la clara separación entre la interfaz de la base de datos y la implementación. Hemos observado los siguientes beneficios:
- La abstracción para la implementación del acceso a la base de datos real separa la estrategia de acceso a los datos de la lógica de negocios del usuario. Esto nos ha permitido elegir una estrategia de implementación a corto plazo (Plantilla JDBC de Primavera) para la fase inicial del proyecto con la opción de pasar a IBATIS o Hibernate en una fecha posterior. (Una elección que no estamos en condiciones de hacer en este momento).
- La separación introduce beneficios significativos de capacidad de prueba, ya que toda la implementación del acceso a los datos se puede simular en las pruebas unitarias. (Este es probablemente el mayor beneficio)
- Combinar esto con Spring nos permite inyectar cualquier implementación de DB en el sistema que elegimos (aunque esto posiblemente dice más sobre DI que el patrón DAO).
Uno de los problemas que encontramos, y esto puede deberse a una falta de claridad en el diseño de nuestra parte, es la "inclinación" a reutilizar los objetos de valor de datos publicados fuera de la base de datos como objetos de transferencia entre las capas de abstracción subsiguientes en la arquitectura. Nuestra solución después de un poco de dolor fue tener un objeto de valor por capa (es decir, no reutilizar los objetos de valor de la base de datos en capas arquitectónicas posteriores).
Las fuerzas del patrón DAO son que le permiten crear una capa de abstracción agradable del sistema de almacenamiento real. Proporcionan una vista más orientada a los objetos de la capa de persistencia y una separación limpia entre el dominio y el código que realmente realizará el acceso a los datos (JDBC directo, marcos de persistencia, ORM o incluso JPA).
Si tuviera que citar una debilidad, bueno, diría que es otra capa ... Pero creo que este es el precio a pagar para no vincular su código con la API de persistencia subyacente.
Los problemas con los DAO que he visto es que normalmente manejan objetos completos todo el tiempo. Esto crea una sobrecarga completamente innecesaria que no existiría con consultas simples. Por ejemplo, si se crea un menú desplegable a partir de los datos de referencia de la base de datos, un usuario de DAO simplemente puede decir: "Consígame la colección de objetos para esta tabla donde y ordenada por z". Luego, esos datos se usan en el menú desplegable, pero generalmente solo para una combinación de clave / valor, ignorando todo lo demás en los objetos (datos creados, último usuario que lo actualizó, esté o no activo, etc.) que se recuperó y asignó . Incluso si este masaje ocurre cerca de la llamada de DAO y los objetos no se almacenan a medida que se recuperan (lo cual no suele ser el caso, desafortunadamente, los objetos a menudo se envuelven en ac: forEach (JSP) y se iteran para producir un menú desplegable). ), aún crea una base de datos innecesaria y sobrecarga de red, sin mencionar el aumento temporal en la memoria para contener estos objetos.
Ahora, esto no quiere decir que un DAO no pueda ser diseñado para recuperar un Mapa de datos de referencia, ciertamente puede. Pero normalmente se usan para la asignación de objetos completa, que no es lo que se necesita todo el tiempo. Es una fortaleza cuando se guarda, pero una debilidad, IMO, cuando se recuperan datos, seguro, se obtiene todo, pero a menudo no se necesita todo, y solo desperdicia memoria, ancho de banda y tiempo.
Pro: separación abstracta.
Con: código repetitivo (gracias a Dios por los generadores de código / plantillas y ORM).
PRO
- único punto de definición para la tabla de DB - asignación de atributos de objeto
- Posibilidad transparente para implementaciones DAO a otros tipos de almacenamiento.
- Desarrollar un patrón de interfaz que todos los DAO siguen.
- desarrollar una clase de prueba de JUnit más o menos estándar para los resultados de DAO en una mejor cobertura de prueba
- control total sobre detalles
- sin pérdida de rendimiento debido a una solución demasiado genérica
ESTAFA
- menos "sexy" que usar el último framework
- los desarrolladores no pueden inventar sus propias ruedas (podría ser un PRO :-))
Al igual que con la mayoría de los patrones de desarrollo, el uso de DAO toma algún tiempo para acostumbrarse. Con la experiencia, vienen los beneficios de un código más robusto y los desarrolladores que saben por qué funcionan las cosas, no solo lo que parece. Ese último punto es la mayor ventaja para mí.
Advertencia: dependiendo de su situación, usar un marco de persistencia podría ser una buena alternativa para codificar sus propios DAO.