Trabajando con persistencia (mal uso de los DAOs)
Todo programador Java sabe lo que es un DAO (Data Access Object).Todo programador Java los utiliza, en practicamente todas las aplicaciones que desarrolla y requieren el acceso a la base de datos.
Todo programador Java esta convencido de que las "buenas prácticas" de programación incitan a usar una capa de DAOs para realizar el acceso a la persistencia de la aplicación.
El uso de este patrón de los "core J2EE patterns" está tan difundido que nadie se pregunta si es correcto o no usarlo: simplemente, hay que tenerlo en una aplicación "seria".
Bueno, yo creo que todo esto es false. Es más, creo que en la mayor parte de los casos el uso del patrón DAO no hace sino agregar complejidad innecesaria a la aplicación.
¡Alto! Por favor, no me prendan fuego ni me griten "hereje" todavía... esperen a escuchar mi historia.
¿Que es el patrón DAO?
El patrón DAO tiene su orígen en los primeros días de J2EE, cuando las condiciones de desarrollo de software era bastante diferente a la actual. Tiene como objetivo ofrecer una capa de abstracción entre la lógica de acceso a datos de fuentes diversas. La idea del patrón es la composicion del modelo lógico a partir de estas fuentes, de forma que el origen de los datos sea transparente a la manipulación de los mismos en la aplicación.
Ok, no hay nada que decir en contra de esto, es una situación descrita en la cual dicha abstracción me vendría de perlas, veamos un ejemplo: supongamos que tengo una base de datos relacional que guarda datos de clientes de un banco, pero con datos de las cuentas de los mismos que residen en un sistema legacy X. Una aplicacion tipo requiere la relación Cliente->Cuentas.
En este caso, es perfectamente entendible el uso de un DAO (que funciona como una Factory de objetos Cliente) para, en el método ClienteDao.get(Id)", obtener una primer versión del cliente desde la base relacional y componer el resto con los datos necesarios provenientes del sistema Legacy.
Pero... ¡el problema es que no es así como se usa!
Hoy la "capa de Dao" es de uso obligatorio en una aplicación Java... aún cuando no hay ninguna necesidad de integración con ningún sistema legacy, y hay una entrada única de datos (lo cual es así en el 99% de los sistemas): Una aplicación java, en general, tendrá un único orígen de datos (una base de datos relacional, normalmente, aunque en muchos casos esto sea totalmente innecesario, pero eso es para otro momento).
Además, con el auge de los ORM (Object Relational Mappers) como Hibernate, se hace por demás estpupido agregar una capa de objetos entre el modelo de negocio y la base de datos. Una capa que, por demás, si esta bien hecha, lo único que hará será llamar a métodos "save", "remove" o "find", todos iguales entre sí.
Mucho más fácil parece ser seguir otro camino:
- Un único singleton para toda la aplicación que realiza las operaciones de acceso a los datos (Hibernate implementa un EntityManager que puede ser utilizado con estos fines).
- Definicion de las consultas necesarias a través de las características que proveen los ORMs. En JEE5 e hibernate esta la annotation @NamedQuery para definir los mismos en el mismo objeto que mapea.
- En caso absolutamente necesario, el uso del patrón "method factory" parece más apropiado que el patrón Dao.
@Table
@NamedQuery("aliveGalaxy", "alive=true")
public class Galaxy {
// Atributos
private String nombre;
private Boolean alive;
// etc.
// Necesito un query muy raro
public static List unQueryRaro() {
//Definicioon del query
return DataManager.getInstance().executeQuery(unQuery);
}
//Resto de la clase
}
Lo que conseguimos en este caso es concentrar todo lo que es referido al objeto "Galaxia" en su definición (como corresponde en una buena programación orientada a objetos), mientras que usando DAOs quedaba distribuido en dos lugares distintos.
Las consecuencias son obvias:
- Reducimos la cantidad de código, o como mínimo lo agrupamos mejor.
- Mejoramos la claridad del código: yo sé que todo lo referente a una galaxia, esta en Galaxia.
- Mejoramos la mantenibilidad, dado que todos los cambios necesarios se concentran en un único punto.
