Modelo de dominio matriarcal

En los últimos días he estado cruzando algunos mensajes en el blog de Julio César Pérez Arques y dado que hemos llegado a un punto donde no lo puedo “despachar” con un par de frases ocurrentes, creo que lo oportuno es explicarlo en un formato más “extenso”.


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.

DDD en español

Resulta que en foro-agiles estábamos discutiendo sobre TDD (Test-Driven Development), BDD (Behaviour-Driven Development) y DDD (Domain-Driven Design) y caímos en que no había ningún foro en español donde discutir y aprender sobre DDD. Así que lo he creado: se llama DDD-es y está en GoogleGroups.

En ocasiones he participado en la lista en inglés sobre DDD, pero es un grupo muy maduro donde a veces el idioma me dificulta las discusiones. Ya saben, ellos bromean contigo haciendo un juego de palabras y tú no sabes siquiera de qué va la cosa… Creo que tener un foro donde expresarnos sin las cortapisas del lenguaje nos ayudará a aprender más rápido y mejor sobre Diseño Basado en el Dominio.

También estoy en el grupo de LinkedIn, pero no siento la necesidad de crear otro en español.

En fin, espero que los que os vayáis uniendo a este foro os presentéis (si así lo deseáis) y que os sintáis libres para preguntar o aportar lo que queráis.

SOA no va de reusar

El pasado día 7 asistí a un curso de un día sobre SOA organizado por iMeta e impartido por el reconocido Udi Dahan. Por cierto que fue en las instalaciones de Microsoft en “La Finca”. Uuuuyyy, qué miedooorrr… Bueno, tampoco es para tanto, soy muy Linux y muy Java, pero tampoco soy tan “talibán” como para no “entrar en la boca del lobo”. :-)

Bueno, bromas aparte, la organización de iMeta fue muy buena (el catering estuvo a la altura, je, je) y Udi Dahan es toda una garantía. Además, como Hadi Hariri (de iMeta) me había explicado, el curso no estaba centrado en ninguna tecnología en particular. Yo, por si acaso, advertí de mi “orientación ideológica” en mi presentación. Por cierto, pensé que mi inglés estaba más oxidado, aunque al final de la tarde ya no daba pié con bola… :-(

Pero vamos al tema. Udi Dahan es muy conocido en ambientes SOA (Service Oriented Architecture) y DDD (Domain-Driven Design) porque tiene un enfoque diferente al SOA de otros autores. Durante el curso le pregunté directamente por esto y sobre cómo se encaja con la visión de, por ejemplo, Thomas Erl. Udi me contestó que simplemente no encajan: el enfoque de Erl se centra en reusar, mientras que el de Dahan se centra en la autonomía de los servicios y el principio de única responsabilidad (single responsibility principle). En un correo posterior, Udi me ha aclarado que, según él, Thomas Erl ve los servicios más como construcciones de software, mientras que él los ve más como construcciones de negocio (implementados mediante varias construcciones de software).

No hace mucho leí “Implementing SOA” de Paul C. Brown, y hay muchas más coincidencias con Dahan que con Erl. Y eso que de Erl tengo nada más y nada menos que tres tochacos que voy a tener que rifar, salvo que el último, “SOA Design Patterns” me sirva para algo más que para hacer bulto en la estantería. :-/

Todo esto que resumo en apenas dos frases queda bastante claro a lo largo del curso porque Udi dedica bastante tiempo a explicar que al reusar realmente incrementamos el acoplamiento mientras que lo que realmente buscamos cuando decimos que queremos reusar es reducir el esfuerzo  empleado al desarrollar las aplicaciones para nuestros clientes. Por ello explica que, aunque sea paradójico, aquellas piezas de código en las que empleamos mayor esfuerzo, y que por tanto serían las que más nos interesaría reusar, suelen ser aquellas que son más específicas y que son las más dificiles de reusar puesto que están fuertemente acopladas al negocio que resuelven. Y por otro lado, resulta que nos empeñamos en que todas nuestras aplicaciones compartan componentes y diseños poco acoplados al negocio (es decir, que no aportan valor de negocio por sí mismos) con el objetivo de que sean lo más reutilizables posible. Pero parece que nos olvidamos de que, hagamos lo que hagamos, en algún punto de nuestro código tendremos que acoplarnos al negocio puesto que para eso desarrollamos software: para resolver problemas de negocio.

Udi nos presenta los conocidos cuatro principios de la orientación a servicios (según Microsoft):
  • los servicios son autónomos
  • los límites son explícitos
  • los servicios comparten esquemas y contratos, no clases
  • la compatibilidad de un servicio se determina en base a una política


y se centra en la autonomía de los servicios. Nos explica cómo alcanzar esa autonomía de una manera genuína, llegando hasta el extremo de que cualquier servicio se pueda implementar con el diseño que se quiera y sin la obligación de compartir siquiera la misma base de datos.


- ¡Eh! ¿Qué ha dicho? ¿Qué no se comparte la base de datos?
- ¿Y qué pasa con las restricciones de integridad? ¿Qué hago con mis foreign keys?


Muchos le preguntaron a Udi por esto. Je, je, yo ya sabía por dónde iba él porque esta discusión me la conozco de cuando estaba en Degesys, aunque allí no llegamos a ninguna conclusión (al menos mientras yo estuve). El caso es que la respuesta es bien fácil: las restricciones de integridad en la base de datos sólo sirven para acoplar servicios entre sí. Así que tú verás si quieres estar acoplado o no… :-) Claro, para conseguir esta autonomía hay hacer concesiones:

  • no tenemos un único modelo de datos compartido por todos los servicios
  • no tendremos un estado coherente de los datos al que estamos acostumbrados
  • tendremos que asumir un cierto nivel de redundancia en nuestros datos almacenados


¿Cómo se consigue esto? Pues Udi lo resuelve de una manera muy sencilla a la vez que elegante:

  • los datos son “propiedad” de una única fuente autorizada, es decir, cada dato en la base de datos sólo es manipulado por un único servicio
  • los servicios interesados en algún dato se suscriben a los cambios que publicará su fuente autorizada y guardan una copia local del dato (a modo de caché)


Esto, si no estoy equivocado, se viene conociendo como Event-Driven Architecture (EDA).

Pero Udi no nos contó sólo que la manera de implementar SOA es haciendo EDA, sino que insistió en que un servicio debe ser concebido desde el negocio y que se implementa íntegramente desde la UI hasta la BD. Para ello nos explicó diferentes maneras de componer la UI, pero todas evitando el concepto de página monolítica. Y recalcó que no tenemos que tener una única capa técnica consistente, sino que podemos decidir usar diferentes soluciones técnicas para cada problema de negocio. Claro, lo difícil es que hay que acertar en definir los “bounded contexts”, y sólo podremos acertar si tenemos claro que éste no es un trabajo tecnológico sino de análisis del negocio.


- ¡Vaya, claro, por eso hablan tanto del alineamiento de IT con el negocio cuando se hace SOA!
- ¡Ahora lo entiendo!
- ¡Y yo que pensaba que todo esto de SOA iba de reusar componentes tecnológicos y poner webservices por doquier!


Si estáis interesados, otro día puedo recopilar más notas y recordar algunos de los ejemplos que usó Udi en el curso.

¡Ah! Y que no se me olvide. Gracias a Hadi por el detalle que tuvo conmigo para Agile Spain. Lo dejo ahí porque si queréis enteraros tendréis que asistir a la charla que darán Juan, Agustín y Leo sobre “Introducción a Scrum”.