DDD con ORM ¿adónde debe ir la lógica de negocios?

10

He utilizado una herramienta MDA (arquitectura basada en modelos) en el pasado donde modelamos a través de UML y esto generó las entidades comerciales (nuestro modelo de dominio) y el ORM (mapeo, etc.) entre otras cosas.

Gran parte del código comercial y los servicios que trabajan en el dominio formaban parte del modelo y nuestros repositorios devolvían las entidades comerciales (por lo que hubiera sido imposible cambiar a otro ORM (no es que quisiéramos)).

Sin embargo, ahora estoy comenzando un proyecto y quiero pensar en términos de DDD.

Hasta ahora parece que puse mi lógica de negocios en mi modelo de dominio y, a través de repositorios, trabajaría con el ORM (el que elija). Sin embargo, si quisiera continuar usando la herramienta MDA para la parte ORM de la aplicación, el modelo creado aquí sería muy anémico (es decir, no contiene ninguna lógica comercial). Del mismo modo, si utilizo Entity Framework (.net) o NHibernate para mi ORM, también sería un modelo anémico. No estoy seguro de dónde pondría la lógica de negocios si solo usara NHibernate.

¿Estoy en lo correcto al pensar de esta manera, en otras palabras, con DDD toda la lógica de negocios en el dominio y solo uso el ORM para la persistencia a través de repositorios?

JD01
fuente

Respuestas:

12

Por lo tanto, hubiera sido imposible cambiar a otro ORM (no es que quisiéramos).

Eso parece mal. Una ventaja importante del patrón de repositorio es que oculta la lógica de acceso a datos y que es fácilmente intercambiable.

Hasta ahora parece que puse mi lógica de negocios en mi modelo de dominio y, a través de repositorios, trabajaría con el ORM (el que elija). Sin embargo, si quisiera continuar usando la herramienta MDA para la parte ORM de la aplicación, el modelo creado aquí sería muy anémico (es decir, no contiene ninguna lógica comercial). Del mismo modo, si utilizo Entity Framework (.net) o NHibernate para mi ORM, también sería un modelo anémico. No estoy seguro de dónde pondría la lógica de negocios si solo usara NHibernate.

Un modelo de dominio anémico es considerado una mala práctica por muchos, por ejemplo, Martin Fowler. Debe evitar dicho diseño porque dicho modelo conduce a técnicas de diseño de procedimientos en lugar de un buen diseño orientado a objetos. Luego tiene clases de datos y clases de administrador / procesamiento, lo que significa que separó el estado y el comportamiento. Pero un objeto realmente debería ser "estado y comportamiento".

NHibernate hace un gran trabajo en la persistencia de la ignorancia. Puede ocultar los detalles de mapeo en XML o con FluentNHibernate y simplemente escribir POCOs simples. Es muy fácil crear un modelo de dominio rico con NHibernate. Creo que también puede hacerlo con el marco de la entidad y la herramienta MDA. Mientras esta herramienta produzca clases parciales, puede extender el código generado con bastante facilidad sin tener que preocuparse de que una nueva generación pueda destruir su código escrito por el usuario.

Para resumir esta larga historia. Cuando usa NHibernate, nada, no repito nada , le impide adoptar un modelo de dominio rico. Recomiendo usarlo con FluentNHibernate y mapear a mano. El código de mapeo tarda solo de 5 a 10 minutos en escribirse. Supongo que lo mismo es cierto para el marco de la entidad y que sus herramientas al menos crean clases parciales que son fácilmente extensibles.

¿Estoy en lo correcto al pensar de esta manera, en otras palabras, con DDD toda la lógica de negocios en el dominio y solo uso el ORM para la persistencia a través de repositorios?

En su mayor parte tienes razón. Debe tener un modelo de dominio rico. Especialmente cuando las cosas se vuelven cada vez más complejas, es más fácil de mantener y extender cuando lo ha diseñado correctamente. Pero tenga en cuenta que DDD también conoce los servicios (capa de dominio y capa de aplicación) para implementar la lógica de negocios y las fábricas para encapsular la lógica de creación.

También tiendo a diferenciar la lógica de negocios en lógica de dominio y lógica de negocios de aplicaciones reales. La lógica del dominio es cómo interactúa y se comporta el dominio, mientras que la lógica de la aplicación, que es una capa completamente diferente, encapsula cómo se usa el dominio para el caso de uso / aplicación específico. Muchas veces tengo que actualizar el modelo de dominio para admitir casos de uso específicos y hacerlo más potente.

Halcón
fuente
2
+1: también separo la capa lógica del dominio de la capa lógica de la aplicación. Puse todo el ORM y las cosas de la base de datos en la capa lógica del dominio. La capa de lógica de la aplicación no sabe nada sobre el ORM, las transacciones y todo eso: solo ve las clases de lógica de negocios y llama a sus métodos. Este enfoque me parece muy efectivo para tener una capa lógica de aplicación más simple y limpia.
Giorgio
@ Falcon: Gracias por la información. Cuando mencioné el modelo anémico, lo que quise decir es que si creo un dominio usando DDD, una versión de mis repositorios posiblemente sería la versión mda donde simplemente movería mis entidades a las entidades mda (es decir, modelo anémico) y luego persistiría en ellas. en transacciones, etc. ¿Estaría bien? Dudo que use la herramienta MDA pero solo trato de entender cómo podría hacerlo si quisiera. ¿Suena bien?
JD01
@ JD01: No te entiendo, pero parece que quieres transformar las entidades del modelo de dominio para que puedas persistirlas fácilmente. Eso es más o menos como usar DTOs y automapper (google it) podría ser una herramienta útil para tal tarea. Tal enfoque no necesariamente interfiere con las mejores prácticas de DDD. Después de todo, los repositorios también están destinados a ocultar la lógica de acceso a datos. Simplemente podría transformar sus objetos de negocios detrás de escena en DTO de MDA y luego persistirlos y el usuario de API ni siquiera lo notaría. Creo que esta bien.
Falcon
1
@ JD01: le sugiero que eche un vistazo al siguiente enlace para ver cuántos muchachos de Enterprise java lo hacen. Básicamente tienen un DAO, un DTO y BO (objeto comercial). Para mí, son demasiadas capas, pero el diseño está bien. java.sun.com/blueprints/corej2eepatterns/Patterns/…
Falcon
@Falcon: Sí, estaba pensando que los DTO eran mis objetos MDA, no que iría por ese camino. Acabo de entender lo que cada parte de los jugadores DDD d0. Gracias una vez más.
JD01
3

Sin embargo, si quisiera continuar usando la herramienta MDA para la parte ORM de la aplicación, el modelo creado aquí sería muy anémico (es decir, no contiene ninguna lógica comercial).

No sé qué herramienta MDA está utilizando, pero con las que he trabajado siempre crean clases parciales, por lo que puede completarlas con tanta lógica empresarial como desee.

Sin embargo, creo que las herramientas MDA son un poco menos apropiadas en un contexto DDD que las ORM, porque la generación de código a menudo tiende a producir clases que se confunden con el ruido específico de la herramienta en lugar de las entidades de dominio simplificadas y claramente expresadas que esperamos. En realidad, lo que a menudo se obtiene es una combinación de datos de dominio, lógica de persistencia, lógica de validación de restricciones ... y no sé si hay una manera de separar estas preocupaciones con la mayoría de las herramientas MDA.

Y, por supuesto, no puede tocar el código generado, excepto a través de clases parciales, lo que significa que no puede eliminar el posible comportamiento anti-DDD que se integraría. Esto es problemático en un enfoque en el que desea imponer barreras estrictas entre los agregados y adaptar a la perfección las relaciones entre sus entidades. El tiempo de construcción en un entorno de integración continua también puede verse afectado por el paso adicional de generación de código.

Aparte de eso, creo que Falcon prácticamente lo dijo todo, absolutamente nada en las herramientas ORM o MDA le impide tener entidades de dominio ricas.

guillaume31
fuente
Hola, estoy usando ECO (objetos centrales empresariales) de ableobjects.com y es exactamente como lo describiste.
JD01
1

Lo que hago en mi equipo es modelar mi objeto, dominio y agregar mi lógica de negocios al mismo tiempo. No uso Model Driven Development que generaría un código de un modelo, pero prefiero el enfoque de anotación. Quiero decir que a nivel de objeto dentro del diagrama de clase agrego estereotipos ORM. Esto agregará anotaciones de persistencia directamente en el código que son compatibles con EJB3 / hibernate. La creación de la base de datos es realizada por Hibernate y ciertamente no por las plantillas UML. Esto es mucho mejor porque si el código cambia y las anotaciones agregadas no son exactamente lo que el especialista en hibernación puede cambiar, pero el modelo sigue siendo bueno. También puedo cambiar mis requisitos y mi modelo de dominio todavía está bien.

Los desarrolladores pueden agregar lógica de negocios dentro de cada método y agregar un comentario, también puedo modelar y agregar restricciones. Por ejemplo, las ventas deberían ser superiores a 50k si no, etc. No necesito codificarlo, solo escriba el modelo y esta información será visible para el equipo de desarrolladores. UML realmente genial y flexible.

UML_GURU
fuente