2010-01-19 14 views
17

Solía ​​diseñar mi aplicación en torno al modelo de dominio anémico, así que tenía muchos objetos de repositorio, que se inyectaban a la capa de servicio grande, gorda y con reconocimiento de transacciones. Este patrón se llama secuencia de comandos de transacción. No se considera una buena práctica ya que conduce al código de procedimiento, por lo que quería avanzar hacia el diseño impulsado por el dominio.Diseño impulsado por dominio y transacciones en el entorno Spring

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 POJOs in Action, creo que tengo una idea general.

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

La capa de presentación se encarga de las peticiones HTTP desde el navegador del usuario llamando el modelo de dominio, ya sea directa o indirectamente a través de una fachada, que como he descrito en el capítulo anterior es o bien un POJO o un EJB.

bien hasta ahora, pero Srini Penchikala en InfoQ article estados:

Algunos desarrolladores prefieren gestionar las transacciones en las clases DAO, que es un mal diseño. Esto da como resultado un control de transacción demasiado detallado que no ofrece la flexibilidad de administrar los casos de uso en los que las transacciones abarcan múltiples objetos de dominio. Las clases de servicio deben manejar las transacciones; De esta forma, 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.

Ok, si entiendo esto correctamente, las clases de repositorio no deben ser transaccionales, la capa de servicio (que ahora es mucho más delgada) es transaccional (como solía ser en el patrón de script de transacción). Pero, ¿qué sucede si los objetos de dominio son invocados directamente por la capa de presentación? ¿Significa que mi objeto de dominio debe tener un comportamiento transaccional? ¿Y cómo implementarlo en el entorno Spring o EJB?

Esto me parece un poco raro, así que estaría feliz si alguien aclara eso. Gracias.

+0

Agregué la etiqueta java, ya que considera todas las clases de DI + ORM (no solo en java, pero ese es su contexto) – Bozho

Respuesta

8

Mi decisió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 de dominio a través de eso. Entonces, de la forma en que lo estoy haciendo, el modelo de dominio no sabe nada sobre las transacciones, que son manejadas completamente por los servicios.

Hay un example application que puede ser útil echar un vistazo. Parece que Eric Evans estuvo involucrado en crearlo.

+0

Gracias por su respuesta. Entonces, por ejemplo, cuando quiere persistir una entidad, llama a service.save (entidad). Mi objetivo es persistir entidades llamando a entity.save(), como describe Craig Wells aquí: http://groups.google.ca/group/EtoE/browse_thread/thread/cac1eafe15f06f5b/ – semberal

+0

Tienes razón, mi código no cosas como service.save (entidad). No me importa el enfoque 'entity.save()', leeré el artículo al que se vinculó y editaré mi respuesta con una explicación.) –

+1

Y en el caso de service.save (entity) qué lógica queda en el objeto de dominio? – Bozho

5

Ver this extremely useful blog-post. Explica cómo lograr una DDD uniforme sin perder las capacidades de Spring y JPA. Se centra alrededor de la anotación @Configurable.

Mi opinión sobre estas cuestiones no es popular. El modelo de datos anémicos en realidad no es incorrecto. En lugar de tener un objeto con datos + operaciones, tiene dos objetos, uno con datos y otro con operaciones. Puede verlos como un solo objeto, es decir, que satisfacen DDD, pero para facilitar su uso son físicamente separados. Lógicamente son lo mismo.

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

En cuanto a las transacciones, hay algo llamado propagación de transacciones. Spring lo admite con @Transactional(propagation=Propagation.REQUIRED). See this, point 9.5.7. En caso de que desee que sus transacciones abarquen múltiples 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, según corresponda, pero esto podría introducir muchas clases de servicio de calderas en los casos en que desee utilizar operaciones sencillas de un solo paso como "guardar".

+0

Hola, gracias por su respuesta. Ya leí ese artículo. Las primeras dos soluciones propuestas son inaceptables. Tampoco me gusta la solución con interceptores de hibernación, porque (hasta donde yo entiendo) solo resuelve la inyección de frijoles con hibernación. La solución de AspectJ parece bastante buena. Solo tendría que descubrir cómo usar transacciones en clases @Configurable. Pero no responde la pregunta, si mi modelo de dominio debe ser transaccional o no. Si no, ¿dónde se supone que son las transacciones? – semberal

+0

Agregué un párrafo con respecto a las transacciones. – Bozho

+0

Lo sé, pero el artículo que publicó menciona que las clases @Configurable no funcionan con @Transactional. – semberal

0

Creo que una forma fácil de comenzar con DDD y Spring y tener buenos ejemplos de cómo lidiar con las transacciones es mirando una de las aplicaciones de muestra que se envían con Spring Roo. Roo produce un código que sigue los principios de DDD. Se basa en gran medida en AspectJ. Sospecho que fue implementado basándose en las ideas presentadas (en 2006) por uno de los pesos pesados ​​de SpringSource, Ramnivas Laddad, in this talk.

Cuestiones relacionadas