En un artículo de su blog, Julio César resumía bastante bien una presentación de Neal Ford en InfoQ, pero dijo algo que nos llevó a iniciar esa “eterna” discusión sobre modelo anémico y modelo rico:
No me gustan nada los constructores con más de 2 parametros. Prefiero uno vacio y luego hacer sets.
Julio César en realidad luego explica la postura de Neal Ford sobre el uso de constructores, más alineada con los modelos ricos que con los modelos anémicos que defiende Julio.
Y ante mi crítica, Julio se excusa (en vano, je, je) diciendo lo siguiente:
No se si es que estoy demasiado Springizado pero me gusta más tener mi capa service y mi capa dao separaditas. Supongo que también tiene que ver con el tipo de aplicaciones en las que trabajo, basicamente de gestión sobre una bbdd ama y señora.
¿Por qué acaso en una aplicación de gestión no son todas las clases del modelo Value Objects? Para mi la unica diferencia es en si mueven los datos del cliente a la app o si de la app a la bbdd. Siempre desde mi pto d vista…
No voy a entrar a discutir si usar Spring y tener las capas de servicios y de acceso a datos desacopladas tienen algo que ver. Para mi no, pero no me interesa discutir ahora sobre frameworks, porque me interesa “atacar” esa idea de que una “aplicación de gestión” es poco más que una aplicación de “data entry”. No estoy de acuerdo. Para nada, una aplicación de gestión es justamente donde más y mejor podemos aplicar el Domain-Driven Design.
Pero voy a usar un viejo artículo de Udi Dahan (al que, sí, es cierto, últimamente cito mucho) en el que explica muy, muy bien cómo y por qué debemos orientar nuestros diseños hacia el modelo de dominio en vez de al CRUD.
Udi pone el ejemplo de un sistema para hacer entrevistas a candidatos en una selección de Recursos Humanos. Y así, si modelamos esta aplicación como un conjunto de inserciones, actualizaciones y eliminaciones de objetos Cita, nuestro código para el servicio de citar a un entrevistado sería algo así como:
Cita cita = new Cita();
cita.setEntrevistador(entrevistador);
entrevistador.getCitas().add(cita);
cita.setCandidato(candidato);
candidato.getCitas().add(cita);
cita.setFechaHora(fechaHora);
dao.guardar(cita);
Pero, en cambio, si nos orientamos al dominio y modelamos el sistema como objetos con estado que se encargan ellos mismos de persistirse cuando cambian de estado (si es necesario), conseguimos que el código de nuestros servicios no sólo no esté acoplado al modelo de datos sino que es más fácil de entender al carecer de artificios tecnológicos:
entrevistador.planificaEntrevistaCon(candidato).enFechaHora(fechaHora);
Si entramos a discutir cómo se implementan estos métodos, a partir de este punto tendremos una gran discusión porque no todos se ponen (nos ponemos) de acuerdo sobre cómo hay que hacerlo. Muchos hablamos de la ignorancia de la persistencia, es decir, de que los objetos de dominio no deben llamar nunca a los DAOs directamente sino que para ello hablan con los Repositorios usando una interfaz tipo Collections. Otros dicen que por qué esa indirección si el 99% de las aplicaciones tienen que persistir los datos. Yo tengo claro que se trata de aplicar los principios SOLID y que, por tanto, lo correcto es desacoplar la lógica de negocio de la lógica de persistencia. Pero para gustos hay colores…
Esta semana lo voy a tener un poco difícil, pero puede que para la semana que viene pueda implementar completo este ejemplo usando Spring y JPA. Espero que la salud mía y de mis niños me lo permita. Je, je…
Para terminar, si a alguien le interesa todo esto del Diseño Orientado al Dominio, le invito a pasarse por la lista de DDD-es que hemos creado recientemente.