driven domain ddd context design-patterns architecture domain-driven-design anti-patterns

design patterns - domain - Modelo de dominio enriquecido y ORM



ddd context (3)

Martin Fowler considera el modelo de dominio anémico como un anti-patrón.

El balanceo del modelo de persistencia como modelo de dominio parece demasiado desviado debido a la falta de coincidencia de la impedancia relacional del objeto . En aras de la persistencia y la normalización, tendemos a dividir las clases en pequeñas partes muy pequeñas, y los métodos de bofetadas que se encuentran encima de estas clases son ridículos. Además, la persistencia rara vez cambia, pero la lógica empresarial cambia un poco.

Por lo tanto, necesitamos un DomainModel que se base en el modelo de persistencia (en lugar de ser el mismo). Este modelo de dominio contendrá las propiedades y el método de la lógica de negocios.

Pero ahora estos Modelos de Dominio aún están detrás del servicio, y para exponerlos al mundo exterior, necesitamos convertirlos a DTO.

Lo estamos haciendo manny mappings aquí.

  1. Persistencia al modelo de dominio
  2. Para convertir el modelo de dominio en DTO para pasar de un servicio a otro

No termina ahí, ya que es posible que el DTO deba asignarse a ViewModel.

Todo eso y el problema de duplicar la lógica de validación aún no desaparecen, porque el cliente desea la validación en tiempo real. ViewModel no sabe nada acerca de la validación, por lo que en un SPA, por ejemplo, se ve obligado a volver a escribir la lógica de validación nuevamente, en el lado del cliente (generalmente en javascript).

Además, los servicios son por naturaleza sin estado (orientados a mensajes o RPC), por lo que estamos haciendo todos estos mapeos, entre Persistence, OO y luego volvemos a Procedural, ¿en qué beneficio? ¿Cómo justificaría el costo en términos prácticos de la mayoría del presupuesto de TI?

Entiendo que tener DDD completo, con raíces agregadas, modelos de dominio, etc. sería "genial", pero ¿cómo puede justificar el costo y el impacto en la productividad de los desarrolladores?

anti-patrón (o antipattern) es un patrón que se usa en operaciones sociales o de negocios o en ingeniería de software que puede usarse comúnmente pero que no es efectivo y / o contraproducente en la práctica.

Y si es así, DDD y Rich Domain Model no encajarían en la definición anti- patrón anterior al Modelo de dominio "Lean". Lo siento, desprecio la palabra cargada, "Anemia".

Al mantener el Modelo de dominio, "Lean", usted realmente permite que se comparta sin violar el "Principio de dependencia abstracto", "No se repita" y el proceso lento, tedioso y propenso a errores de asignar un soporte de datos a otro. y cualquier prueba de unidad asociada que vaya más allá de eso (a menos que esté pensando en hacer un mapeo sin pruebas de unidad y espere lo mejor).


En primer lugar, no creo que realmente pueda evitar duplicar la lógica de validación en el cliente y en el servidor. Sin embargo, esto no se limita a DDD. Existen algunos mecanismos para aliviar el dolor, pero siempre se requerirá algún esfuerzo.

La otra parte es todo este negocio de mapeo :)

Lo que está haciendo está utilizando efectivamente para realizar lecturas. Puede estar pensando que necesita leer su entidad para editarla. Esto es cierto si está realizando operaciones basadas en entidades (entidad probablemente más en términos de DB aquí - registro completo) en lugar de operaciones basadas en tareas en su objeto de entidad. Un ejemplo tonto puede ser que un cliente llame al centro de llamadas para cambiar una dirección . El operador llama el registro del cliente y edita la dirección. Esto se basa en entidades y conduce a problemas típicos de concurrencia ya que se pueden realizar 2 acciones en el mismo registro (aunque sea poco probable). Este es un enfoque muy tradicional para el diseño de UX: "Editar el registro".

Contraste esto con un botón en la pantalla que dice: " cambiar una dirección ". Solo cambia la dirección en el registro y, aunque parece ser lo mismo, es bastante diferente. Las posibilidades de 2 operaciones que cambien la misma dirección son bastante más reducidas que las de cambiar el mismo registro. Si es necesario, se puede realizar una verificación de concurrencia en esta parte.

Ahora si uno no lee el dominio lo que uno leería. ¿De dónde provendrían los datos? Aquí es donde entra en juego CQRS (Comando / Separación de Responsabilidad de Consulta). En el pasado, se confundió / combinó con Event Sourcing, pero esto no es necesario. Puede crear un lado de consulta simple para su aplicación centrado en devolver los datos que necesita. En C # utilicé un DataRow si es una instancia única, un DataTable para múltiples instancias y un DTO personalizado para algo más complejo. Puede haber una manera en la que uno se salga con los tipos anónimos (aún no lo he investigado).

Por lo tanto:

Modelo de dominio = operaciones / cálculo / servicios de consulta de escritura = lectura

Existe una situación en la que puede salirse con la simple carga de una entidad / agregado como en una aplicación web, ya que es consciente (o puede ser consciente) de su modelo de dominio, pero un cliente inteligente sería un poco anti-patrón.

La justificación es bastante complicada, pero se reduce al mantenimiento. Si su enfoque no está aliviando su carga de mantenimiento, entonces es probable que algo no se aplique correctamente y necesite un poco de refactorización.

DDD no solo se trata de la implementación técnica, aunque eso va en gran medida, empujando en la dirección del modelado OO adecuado. Supongo que las otras ideas se incorporan al software de todos modos, de modo que el software parece ser el foco de todos modos. Todos queremos ver donde el caucho se encuentra con el camino.

Como la mayoría de las cosas DDD se puede hacer mal :)


Parece que estás mezclando muchos conceptos, culpando al enfoque de modelo de dominio rico por cosas de las que no es directamente responsable.

  • El modelo de dominio enriquecido es ortogonal a la arquitectura en capas, especialmente al tener un modelo de dominio enriquecido que no dicta la cantidad de capas que tiene, qué estructuras de datos deben intercambiarse entre estas capas y cómo deben asignarse.

  • El modelo de dominio enriquecido es ortogonal a la validación y no dice nada acerca de la necesidad de verificación del lado del cliente además de la validación de back-end.

En otras palabras, hacer que su modelo de dominio sea anémico con toda la lógica de negocios en los servicios no necesariamente evitará que escriba una gran cantidad de código de asignación DTO repetitivo, ni eliminará la necesidad de una "doble verificación" del lado del cliente forma una buena práctica comúnmente aceptada).

Esto no significa que su punto sobre el costo y el peso de una arquitectura de múltiples capas en toda regla no sea válido. Es posible que encuentre interés en este post de Mark Seemann sobre temas similares: http://blog.ploeh.dk/2012/02/09/IsLayeringWorthTheMapping.aspx


tl; dr El modelo de dominio no está bien definido, probablemente está diseñado teniendo en cuenta un enfoque centrado en la base de datos.

El propósito principal de DDD es modelar en código los conceptos y procesos de negocios. Realmente dudo que los conceptos y procesos de su negocio sean solo bolsas de propiedades. Pero si realmente lo son, entonces sí, el Modelo de dominio puede ser el mismo que el Modelo de persistencia para que no tenga que hacer ningún mapeo.

El modelo de persistencia modela cómo se almacena el estado del objeto . Si no está en el dominio de las bases de datos, el dominio y el modelo de persistencia no pueden tener el mismo propósito. Uno de los errores más grandes que veo con DDD es pensar en el modelo de dominio como si todavía estuviera basado en datos. En DDD no tienes una base de datos concreta. Tienes repositorios. No hay relaciones de uno a muchos, de muchos a muchos, etc. No hay tablas ni filas. Solo hay objetos que intentan representar el dominio lo más preciso posible.

En pocas palabras, el Dominio se preocupa por modelar el comportamiento empresarial, mientras que la Persistencia se preocupa por almacenar el estado del objeto. Veo dos responsabilidades diferentes aquí.

Acerca de la validación, tiene 2 tipos: validación del formato de datos de entrada y, a continuación, validación de otras reglas comerciales de acuerdo con lo que cambia en un estado de objeto.

Acerca de la duplicación, creo que te refieres al formato de entrada, pero como @EbenRoux dijo que hay un mecanismo que puede ayudar con eso. En asp.net mvc, la mayoría de esas reglas de validación también incluyen la versión js.

Déjame contarte un pequeño secreto con los servicios. Si bien su interfaz se puede definir en el Dominio, su implementación puede ubicarse en la Capa de Persistencia, lo que les permite trabajar directamente con el almacenamiento. Y como el resto de la aplicación utiliza el servicio en su forma abstracta (la interfaz), solo el contenedor de DI conocerá el secreto sucio.

DDD no se trata de ser genial, se trata de diseñar una aplicación de acuerdo con el dominio. Apuesto a que pocos desarrollarán una aplicación con el único propósito de ser una interfaz de usuario para la db. La mayoría tiene como objetivo proporcionar un servicio con su software, para construir un producto virtual que resuelva un problema. Es lógico que el diseño de la aplicación se maneje para resolver el problema que desea resolver y no las herramientas técnicas que utiliza.

Cómo suena esto, quieres una casa de ladrillos pero el constructor dice: "Lo siento, pero mi sierra solo funciona con madera". Bueno, no use una sierra, use otra herramienta que pueda ayudar a cortar un ladrillo. Las herramientas deben adaptarse al problema, no viceversa.