java design-patterns spring oop domain-driven-design

java - Diseño impulsado por dominios y transacciones en entorno Spring



design-patterns oop (4)

Creo que una manera fácil de comenzar con DDD y Spring y tener buenos ejemplos de cómo manejar transacciones es mirar una de las aplicaciones de muestra que se entregan con Spring Roo . Roo produce un código que sigue los principios de DDD. Se basa en gran medida en AspectJ. Sospecho que se implementó sobre la base de las ideas presentadas (en 2006) por uno de los pesos pesados ​​de SpringSource, Ramnivas Laddad, en esta charla .

Solía ​​diseñar mi aplicación en torno al modelo de dominio anémico, por lo que tenía muchos objetos de repositorio, que se inyectaban en la capa de servicio grande, grande y sensible a las transacciones. Este patrón se llama Transaction script. No se considera una buena práctica, ya que conduce al código de procedimiento, por lo que quería seguir adelante con el diseño impulsado por el dominio.

Después de leer un par de artículos en la web, escuchar la charla de Chris Richardson sobre Parleys y leer los capítulos de DDD de los POJO en Acción, creo que tengo el panorama general.

El problema es, que no sé, cómo organizar transacciones en mi aplicación. Chis Richardson en su libro dice:

El nivel de presentación maneja las solicitudes HTTP desde el navegador del usuario llamando al modelo de dominio directa o indirectamente a través de una fachada, que, como describí en el capítulo anterior, es un POJO o un EJB.

Bueno hasta ahora, pero Srini Penchikala en el artículo de InfoQ afirma:

Algunos desarrolladores prefieren administrar las transacciones en las clases DAO, que es un diseño deficiente. Esto da como resultado un control de transacciones demasiado preciso que no brinda la flexibilidad de administrar los casos de uso en los que las transacciones abarcan varios objetos de dominio. Las clases de servicio deben manejar transacciones; De esta manera, incluso si la transacción abarca varios objetos de dominio, la clase de servicio puede gestionar la transacción, ya que en la mayoría de los casos de uso, la clase de Servicio maneja el flujo de control.

Bien, si entiendo esto correctamente, las clases del repositorio no deberían ser transaccionales, la capa de servicio (que ahora es mucho más delgada) es transaccional (como solía estar en el patrón de secuencia de comandos de Transacción). Pero, ¿y si los objetos de dominio son llamados directamente por la capa de presentación? ¿Significa que mi objeto de dominio debería tener un comportamiento transaccional? ¿Y cómo implementarlo en Spring o en entorno EJB?

Esto me parece extraño, así que me alegraría que alguien lo aclarara. Gracias.


Desafortunadamente, no me he familiarizado con Spring, pero le daré una respuesta sobre su comprensión de DDD. Al leer su descripción de la transacción, es obvio que no entiende el DDD, especialmente el concepto de Agregado, Raíz de Agregado y Repositorio.

En DDD, la transacción no puede abarcar agregados, por lo que un Agregado siempre tendrá una transacción.


Mi opinión personal sobre la aplicación de DDD con Spring e Hibernate, hasta ahora, es tener una capa de servicio transaccional sin estado y acceder a los objetos del dominio a través de eso. Entonces, de la forma en que lo estoy haciendo, el modelo de dominio no conoce las transacciones en absoluto, eso es manejado completamente por los servicios.

Hay una aplicación de ejemplo que puede ser útil para echar un vistazo. Parece que Eric Evans estuvo involucrado en su creación.


Vea este blog extremadamente útil . Explica cómo lograr un DDD uniforme sin perder las capacidades de Spring y JPA. Se centra alrededor de la anotación @Configurable .

Mi opinión sobre estos asuntos es un poco no popular. El modelo de datos anémicos no está realmente mal. En lugar de tener un objeto con operaciones de datos +, tiene dos objetos, uno con datos y otro con operaciones. Puede verlos como un solo objeto, es decir, satisfacer DDD, pero para un uso más fácil están separados físicamente . Lógicamente son lo mismo.

Sí, esto rompe la encapsulación, pero no hace que uses algo de ''magia'' (agente aop + java) para lograr tus objetivos.

En cuanto a las transacciones, hay algo que se llama propagación de transacciones. Spring lo admite con @Transactional(propagation=Propagation.REQUIRED) . Ver esto, punto 9.5.7 . En caso de que desee que sus transacciones abarquen varios métodos (de múltiples objetos), puede cambiar el atributo de propagación en consecuencia.

También puede usar @Transactional en su capa de servicio, donde sea apropiado, pero esto podría introducir muchas clases de servicio en el lugar de la caldera en los casos en que quiera usar operaciones simples de un solo paso como "guardar".