Modelo de dominio anémico: pros / contras

Respuestas:

39

Los profesionales:

  • Puede reclamar que es un modelo de dominio y presumir ante sus amigos desarrolladores y ponerlo en su currículum.
  • Es fácil de generar automáticamente a partir de tablas de bases de datos.
  • Se asigna sorprendentemente bien a los objetos de transferencia de datos.

Los contras:

  • La lógica de su dominio existe en otro lugar, probablemente en una clase llena de métodos de clase (estáticos). O su código GUI. O en varios lugares, todos con lógica conflictiva.
  • Es un anti-patrón, por lo que otros desarrolladores le preguntarán si comprende los conceptos del diseño orientado a objetos.
Terry Wilcox
fuente
7
+1 El punto sobre la generación de código a partir de tablas de bases de datos es muy importante para algunas personas. Si está en un modo de desarrollo de creación rápida de prototipos, la generación automática de código es extremadamente útil. No pretendemos que este sea el diseño adecuado de OO, y poner las cosas juntas de manera descuidada produce "deuda técnica". Sin embargo, en muchos proyectos el tiempo de comercialización es una prioridad más alta.
Bill Karwin
62
No. Si un modelo anémico es un anti-patrón es una cuestión de opinión. Fowler (cuyo trabajo respeto y sigo normalmente) dice que sí. No estoy de acuerdo (no es que mi palabra tenga ningún peso), y muchos en las trincheras de OO también están en desacuerdo. El modelado puro de OO no es generalmente aplicable en todos los casos, lo que toda la industria conoce por experiencia. Además, un modelo anémico aún puede cumplir con las pautas de modelado OO. Por lo tanto, ver casos específicos en los que se aplica no cuestiona la comprensión del diseño OO.
luis.espinal
12
Si algún patrón es un anti-patrón es una cuestión de opinión. Un modelo de dominio robusto es un buen diseño OO y un modelo de dominio anémico es un mal diseño OO. Por lo tanto, en el contexto de OO, es un anti-patrón. Eso no significa que no se use o sea inapropiado en todos los casos, pero por experiencia personal lo considero peor que la adicción al singleton.
Terry Wilcox
7
Siento que hay una tendencia hacia la programación funcional y el modelo de dominio tiende a tener muchos efectos secundarios. Tengo la sensación de que el modelo de dominio anémico está regresando porque permite un estilo de programación más funcional, en el que la lógica de su negocio espera la entrada de datos y devuelve los datos procesados. Su capa de servicio supervisa el flujo de todo, al saber qué datos se deben procesar mediante qué método de lógica empresarial.
Didier A.
2
@TerryWilcox Bueno, no soy un experto funcional, pero la programación funcional también tiene estructuras de datos. Un modelo de dominio anémico usa objetos como contenedores de datos, son más como estructuras. Mi punto es que con ADM, puede moverse hacia una forma más funcional, donde tiene datos inmutables que se transforman con el tiempo en estados cada vez más nuevos. Puedo ver que esto se hace en Scala, por ejemplo, tratando de aprovechar un poco de OOP y aplicarle algo de FP. Un poco como lo explican aquí: slideshare.net/debasishg/qconny-12
Didier A.
131

Con el "Modelo de dominio anémico" siendo anti-patrón, ¿por qué hay tantos sistemas que implementan esto?

Creo que hay varias razones

1. Complejidad del sistema

En un sistema simple (que son casi todos los ejemplos y código de muestra que encuentra en Internet) si quiero implementar:

Agregar producto al pedido

Pongo esta función en la Orden

public void Order.AddOrderLine(Product product)
{
    OrderLines.Add(new OrderLine(product));
}

Agradable y super orientado a objetos.

Ahora digamos que necesito asegurarme de que necesito validar que el producto existe en el inventario y lanzar una excepción si no es así.

Realmente ya no puedo ponerlo en Pedido, ya que no quiero que mi pedido dependa del Inventario, por lo que ahora debe ingresar al servicio.

public void OrderService.AddOrderLine(Order order, Product product)
{
    if (!InventoryService.Has(product)
       throw new AddProductException

    order.AddOrderLine(product);
}

También podría pasar IInventoryService a Order.AddOrderLine, que es otra opción, pero eso aún hace que Order dependa de InventoryService.

Todavía hay alguna funcionalidad en Order.AddOrderLine, pero por lo general se limita al alcance del Pedido, mientras que en mi experiencia hay mucha más Lógica Comercial fuera del alcance del Pedido.

Cuando el sistema es más que CRUD básico, terminará con la mayor parte de su lógica en OrderService y muy poca en Order.

2. Visión del desarrollador de la programación orientada a objetos

Hay muchas discusiones acaloradas en Internet sobre qué lógica debería aplicarse a las entidades.

Algo como

Order.Save

¿Debería el Orden saber salvarse o no? Digamos que tenemos repositorios para eso.

Ahora, ¿puede Order agregar líneas de pedido? Si trato de darle sentido usando un inglés simple, tampoco tiene sentido. El usuario agrega un producto al pedido, entonces, ¿deberíamos hacerlo User.AddOrderLineToOrder ()? Eso parece una exageración.

¿Qué hay de OrderService.AddOrderLine (). ¡Ahora tiene algo de sentido!

Mi comprensión de OOP es que para la encapsulación se colocan funciones en clases donde la función necesitará acceder al estado interno de la clase. Si necesito acceder a la colección Order.OrderLines, pongo Order.AddOrderLine () en Order. De esta forma, el estado interno de la clase no queda expuesto.

3. Contenedores de IoC

Los sistemas que utilizan contenedores de IoC suelen ser completamente anémicos.

Se debe a que puede probar sus servicios / repositorios que tienen interfaces, pero no puede probar objetos de dominio (fácilmente), a menos que ponga interfaces en todos ellos.

Dado que "IoC" se alaba actualmente como una solución para todos sus problemas de programación, mucha gente lo sigue ciegamente y de esta manera terminan con modelos de dominio anémicos.

4. OOP es difícil, el procedimiento es fácil

Tengo un poco de " Maldición del conocimiento " en este caso, pero he descubierto que para los desarrolladores más nuevos tener DTO y servicios es mucho más fácil que Rich Domain.

Posiblemente sea porque con Rich Domain es más difícil saber en qué clases poner la lógica. ¿Cuándo crear nuevas clases? ¿Qué patrones usar? etc ..

Con los servicios apátridas, simplemente lo abofetea en el servicio con el nombre más cercano.

Eric P
fuente
Creo que dependería de lo complejo que se volviera. 1. Si es simple como en 1-2 dependencias, lo mantendría en la clase Order. 2. Si es de complejidad moderada, crearía la clase OrderLines y usaría Order.OrderLines para manejar la comunicación Order <-> OrderLines, así como las dependencias relacionadas. 3. Pero en caso de alta complejidad, usaría el servicio de aplicación OrderService para permitir la mayoría de las dependencias externas, mientras mantengo la lógica de alcance del módulo Order en Order.
Eric P
13
Gran resumen: todas estas razones explican por qué no es un anti-patrón. La devoción servil a OO es un antipatrón. Ahora agregue concurrencia sin proyección y observe cómo se ata en nudos con OO estilo Fowler. Observe las empresas que realizan simultaneidad a escala (por ejemplo, google) y vea cuánto OO están haciendo.
DanH
Bien dicho. Usando Grails, no estoy seguro de que 3 ° lleve a la anemia. En cuanto a 1 °, de hecho, termina moviendo la lógica en la capa de servicio en cualquier aplicación no trivial. Pero todavía me encuentro con un enfoque centrado en el dominio usando Grails. Lo que hace que en realidad no sea tan bueno, ya que su dominio es su lugar preferido para la lógica, pero mueve bits una capa cuando es necesario.
youri
4
No veo la correlación de IoC a anémica. Parece un problema completamente ajeno. Si sus servicios / repositorios O los objetos de dominio implementan interfaces no tiene nada que ver con probarlos. Por el contrario, prueba servicios / repositorios / objetos de dominio y los desacopla de sus dependencias que implementan interfaces. Y si lo hace bien o no, no tiene ninguna correlación con IoC que pueda ver.
2
Lo que tengo que hacer con DDD con Grok es su primer punto: "Cuando el sistema sea más que CRUD básico, terminará con la mayor parte de su lógica en OrderService y muy poca en Order". Eso tiene sentido para mí, pero ¿no es el propósito de DDD ser utilizado para sistemas que son más complejos que eso?
Dan Ling
20

Después de esto, ha habido un pensamiento en mi cabeza durante mucho tiempo. Creo que el término "OOP" ha adquirido un significado que no está realmente destinado a él. El anagrama significa "programación orientada a objetos", como todos sabemos. El enfoque, por supuesto, está en la palabra "orientado". No es "OMP", que significa "programación ordenada por objetos". Tanto ADM como RDM son ejemplos de POO. Hacen uso de interfaces de objetos, propiedades, métodos, etc. Sin embargo, hay una diferencia entre ADM y RDM en cómo elegimos encapular las cosas. Son dos cosas diferentes. Decir que ADM es malo OOP no es una afirmación precisa. Quizás necesitemos términos diferentes para distintos niveles de encapsulación. Además, nunca me gustó el término anti-patrón. Por lo general, los miembros de un grupo opuesto lo asignan a algo. Tanto ADM como RDM son patrones válidos, simplemente tienen diferentes objetivos en mente y están destinados a resolver diferentes necesidades comerciales. Aquellos de nosotros que practicamos DDD deberíamos, como mínimo, apreciar esto, y no caer al nivel de otros atacando a aquellos que eligen implementar ADM. Solo mis pensamientos.

Dibujó
fuente
16

"Es un anti-patrón, por lo que otros desarrolladores le preguntarán si comprende los conceptos del diseño orientado a objetos".

"Un modelo de dominio anémico es un anti-patrón. Los anti-patrones no tienen ventajas".

Si el modelo de dominio anémico es un antipatrón es una cuestión de opinión. Martin Fowler dice que lo es, varios desarrolladores que conocen OO de adentro hacia afuera dicen que no lo es. Declarar la opinión como un hecho rara vez es útil.

Y, incluso si se aceptara universalmente como un anti-patrón, lo más probable es que todavía tenga alguna ventaja (aunque relativamente pequeña).


fuente
2
... cuales son? No estoy tratando de engañarte a ti ni a nadie, pero tengo mucha curiosidad por los profesionales. Las desventajas se han mencionado miles de veces, pero sigo buscando ventajas sólidas del ADM (aparte de las frases polémicas).
struppi
6
... esto parece como si alguien estuviera tratando de jugar al adorador del diablo con poco espectáculo. the chances are it would still have some (though relatively little) upside.¡Entonces por favor nombre algunos! ¡Al menos uno, en lugar de hacer hipótesis!
Trineo
2
Es más fácil saber dónde pertenece la lógica para cualquier cosa que no esté relacionada con una sola clase (cualquier negocio real). Como se dijo en otros lugares, el "modelo de dominio rico" termina teniendo lógica en múltiples lugares (capa de servicio, múltiples clases involucradas en gráficos de objetos, ...). Además, RDM no le permite tener una visión sencilla de la lógica empresarial completa, no facilita evitar ciclos, etc. Las estructuras de datos tontas sin lógica tienen su lugar en una aplicación OO.
ymajoros
1
Encuentro que este artículo ofrece un buen argumento para decir que ADM no es un antipatrón blog.inf.ed.ac.uk/sapm/2014/02/04/…
syclee
1
Los antipatrones siempre crean problemas y hemos enviado con éxito varias aplicaciones algo grandes (2 o 3 años de desarrollo de 10 desarrolladores trabajan> 300KLOC) con soluciones de alta calidad utilizando el patrón y sin sentir que algo andaba mal, por lo que no puede ser tan malo si le permite crear un buen código mientras lo usa.
Ignacio Soler García
13

Me parece que la principal objeción de Fowler es que los ADM no son OO, en el siguiente sentido. Si uno diseña un sistema "desde cero" alrededor de estructuras de datos pasivas que son manipuladas por otras piezas de código, entonces esto ciertamente huele más a diseño procedimental que a diseño orientado a objetos.

Sugiero que hay al menos dos fuerzas que pueden producir este tipo de diseño:

  1. Diseñadores / programadores que todavía piensan que deben trabajar en un entorno orientado a objetos (o suponiendo que pueden ...) producir un nuevo sistema, y

  2. Desarrolladores que trabajan para poner una "cara" similar a un servicio en un sistema heredado diseñado de manera no orientada a objetos (independientemente del idioma)

Si, por ejemplo, se estuviera construyendo un conjunto de servicios para exponer la funcionalidad de una aplicación de mainframe COBOL existente, se podrían definir servicios e interfaces en términos de un modelo conceptual que no refleja las estructuras de datos internas de COBOL. Sin embargo, si el servicio asigna el nuevo modelo a los datos heredados para usar la implementación existente pero oculta, entonces el nuevo modelo podría ser "anémico" en el sentido del artículo de Fowler, por ejemplo, un conjunto de definiciones de estilo TransferObject. y relaciones sin comportamiento real.

Este tipo de compromiso puede muy bien ser común para los límites en los que los sistemas OO idealistamente puros deben interactuar con un entorno no OO existente.

joel.neely
fuente
8

El modelo de dominio anémico (ADM) puede ser una buena opción si su equipo no puede o no quiere construir un modelo de dominio rico (RDM) y mantenerlo a lo largo del tiempo. Ganar con un RDM requiere una cuidadosa atención a las abstracciones dominantes utilizadas en el sistema. Imagínese que, en cualquier grupo de desarrollo, no más de la mitad y quizás solo una décima parte de sus miembros son competentes con las abstracciones. A menos que este cuadro (quizás solo un desarrollador) sea capaz de mantener la influencia sobre las actividades de todo el grupo, el RDM sucumbirá a la entropía.

Y el RDM entrópico duele, de formas particulares. Sus desarrolladores aprenderán duras lecciones. Al principio, podrán cumplir con las expectativas de sus grupos de interés, porque no tendrán un historial que cumplir. Pero a medida que su sistema se vuelve más complicado (no complejo) , se volverá frágil; los desarrolladores intentarán reutilizar el código, pero tienden a inducir nuevos errores o retroceder en el desarrollo (y así sobrepasar sus estimaciones).

Por el contrario, los desarrolladores de ADM establecerán expectativas más bajas para sí mismos, porque no esperarán reutilizar tanto código para nuevas funciones. Con el tiempo, tendrán un sistema con muchas inconsistencias, pero probablemente no se romperá inesperadamente. Su tiempo de comercialización será más largo que con un RDM exitoso, pero es poco probable que sus partes interesadas perciban esta posibilidad.

Ladlestein
fuente
5

"Desarrolladores que trabajan para poner una" cara "similar a un servicio en un sistema heredado diseñado de manera no orientada a objetos (independientemente del idioma)".

Si piensa en muchas aplicaciones LOB, estos sistemas heredados a menudo no usarán el mismo modelo de dominio que usted. El modelo de dominio anémico resuelve esto con el uso de lógica empresarial en clases de servicio. Podría poner todo este código de interfaz dentro de su modelo (en el sentido tradicional de OO), pero normalmente termina perdiendo la modularidad.


fuente
1
Bingo. Aquí es donde mucha gente parece perder el barco. Los ADM tienen un propósito. Su mal uso es un anti-patrón, pero ellos mismos no lo son.
luis.espinal
4

Cuando me encontré por primera vez con el artículo del Modelo de dominio anémico pensé "mierda sagrada, eso es lo que hago. ¡Horror!" Perseveré y seguí las referencias al libro de Eric Evan, considerado un buen ejemplo, y descargué la fuente. Resulta que "no usar un modelo de dominio anémico" no significa "no usar clases de servicio, no usar mediadores, no usar estrategias" o incluso "poner lógica en la clase que está siendo manipulada".

Los ejemplos de DDD tienen clases de servicio, XyzUpdaters, singletons e IoC.

Sigo confundido por lo que es exactamente un modelo de dominio anémico. Espero "Lo sabré cuando lo vea". Por ahora me contento con un ejemplo positivo de buen diseño.

Jamie
fuente
1
Posteriormente compré el libro de Eric Evan y lo recomiendo encarecidamente. Proporciona ejemplos sólidos de lo contrario de los modelos de dominio anémicos.
Jamie
4

Habiendo trabajado con un sistema 'maduro' con un ADM y siento que puedo proporcionar, al menos, comentarios anecdóticos a esta pregunta.

1) Falta de encapsulación

En un sistema en vivo con un ADM, existe la posibilidad de escribir, por ejemplo, 'obj.x = 100; obj.save ', incluso si infringe la lógica empresarial. Esto conduce a una serie de errores que no se encontrarían si las invariantes se modelaran en el objeto. Es la gravedad y la omnipresencia de estos errores lo que creo que es el aspecto negativo más grave para un ADM.

Creo que es importante señalar aquí que aquí es donde una solución funcional y las soluciones de procedimiento de un ADM difieren significativamente y cualquier similitud que otros puedan haber extraído de las similitudes superficiales entre un ADM y una solución funcional son incidentales.

2) Código hinchado

Calculo que la cantidad de código producido en un ADM es 5-10 veces mayor que la que crearía una solución OOP / RDM. Esto se explica porque quizás el 50% sea la repetición de código, el 30% sea el código de la placa de la caldera y el 20% sea la solución o resolución de problemas que surgen de la falta de un RDM.

3) Escasa comprensión de los problemas del dominio

Un ADM y una comprensión deficiente de los problemas del dominio van de la mano. Surgen soluciones ingenuas, los requisitos están mal considerados debido a la dificultad de soportarlos con el DM existente, y el ADM se convierte en una barrera importante para la innovación empresarial dados los tiempos de desarrollo más largos y la falta de flexibilidad.

4) Dificultad de mantenimiento

Se requiere cierto nivel de rigor para asegurar que un concepto de dominio se cambie en todos los lugares en los que se expresa, dado que el concepto puede no ser solo una reimplementación de copiar y pegar. Esto a menudo lleva a que se investiguen y corrijan los mismos errores en múltiples ocasiones.

5) Mayor dificultad con la incorporación

Creo que uno de los beneficios de un RDM es la cohesión de conceptos que permiten una comprensión más rápida del dominio. Con un ADM, los conceptos pueden estar fragmentados y carecer de claridad, por lo que es más difícil de adquirir para los nuevos desarrolladores.

También estuve tentado de incluir que los costos de soporte operativo para un ADM eran más altos que para un RDM, pero esto dependería de varios factores.

Como otros han señalado, mire a DDD (Greg Evans, Vince Vaughn y Scott Millett) para conocer los beneficios de un RDM.

Señor morphe
fuente
1
¿Es Greg Evans el hijo secreto de Greg Young y Eric Evans? No sabía que Vince Vaughn estaba escribiendo los libros DDD bien, pero tal vez Vaughn Vernon ha comenzado a actuar también :)
knittl
Oh cielos, parece que mi memoria cuando escribí lo anterior estaba algo confusa. Gracias por señalarlo :)
Mr Morphe
2

Es el mismo profesional que con la mayoría de los anti-patrones: te permite mantener a muchas personas ocupadas durante mucho tiempo. Como los gerentes tienden a cobrar más cuando manejan a más personas, existe un fuerte incentivo para no mejorar.

Stephan Eggermont
fuente
7
En ese caso, déjame reformularlo. ^^^ Evidencia puramente anecdótica utilizada para inferir una proposición que suena general.
luis.espinal
Cuando encontremos suficiente evidencia anecdótica, podríamos derivar un patrón. Y este patrón es bien conocido y se describe adecuadamente en la literatura sobre gestión del cambio.
Stephan Eggermont
4
"Y este patrón es bien conocido y se describe adecuadamente en la literatura sobre gestión del cambio". - Citas por favor. Más concretamente, la correlación no implica causalidad . Es decir, el hecho de que vea a la gente girando sus ruedas en la burocracia debido a antipatrones en el lugar (patrones de software específicamente, y modelos de dominio anémicos hasta el punto), eso no implica que lo último exista para justificar lo primero, que es lo que acabas de pregonar. Los lemas retóricos son pobres caricaturas para explicar temas complejos. Entonces, nuevamente, correlación no significa causalidad.
luis.espinal
4
Es posible que desee leer Quality Software Management de Gerald M. Weinberg, especialmente el Volumen 4. Y solo afirmo una posible causa de la existencia continua, no de su ocurrencia. El Principio de Peter proporciona una alternativa adecuada.
Stephan Eggermont
Gracias, lo leeré cuando tenga la oportunidad (+1 por proporcionar una cita). ¿Ese libro lo presenta como un antipatrón bien conocido? Además de eso, ¿afirma / muestra no solo correlación sino también causalidad ? Lo reclamas como una explicación "posible" ahora . Su texto original lo expresa como una certeza, con más retórica que detalle (por eso lo llamé 'pura especulación'). Si esa fue tu intención entonces , o simplemente un accidente editorial, quién sabe, y solo puedo inferir de lo que está presente en el texto en el momento de leerlo.
luis.espinal
2

De acuerdo con la respuesta de Eric P, así como con lo que algunos otros escribieron anteriormente, parece que la principal desventaja de un ADM es la pérdida de OOD, específicamente de mantener la lógica y los datos de un concepto de dominio juntos para que los detalles de implementación estén ocultos mientras la API puede ser rica.

Eric continúa señalando que a menudo hay información fuera de una clase de dominio que es necesaria para la lógica de actuar en esa clase, como verificar un inventario antes de agregar un artículo a un pedido. Sin embargo, me pregunto si la respuesta es una capa de servicio que mantiene esta lógica general, o si se maneja mejor como parte del diseño del objeto. Alguien tiene que conocer el objeto Inventario, el objeto Producto y el objeto Pedido. Quizás sea simplemente un objeto OrderSystem, que tiene un miembro de Inventario, una lista de Pedidos, etc. Esto no se verá muy diferente de un Servicio, pero creo que es conceptualmente más coherente.

O mírelo de esta manera: puede tener un usuario con un saldo de crédito interno, y cada vez que se llama a ese User.addItemToOrder (artículo), obtiene el precio del artículo y verifica el crédito antes de agregarlo, etc. Eso parece un OO razonable diseño. No estoy seguro de qué se pierde al reemplazarlo con Service.addItemToUserOrder (usuario, elemento), pero tampoco estoy seguro de qué se ha ganado. Supongo que una pérdida sería la capa adicional de código, más el estilo de escritura más tosco y la ignorancia forzada del modelo de dominio subyacente.

Miguel
fuente
1

Cabe señalar que a medida que los sistemas aumentan en complejidad y granularidad de variación, la encapsulación y consolidación de los puntos de interfaz que ofrece un modelo de objetos de paso de mensajes bien diseñado hace que sea mucho más seguro cambiar y mantener el código crítico sin una refactorización generalizada.

Las capas de servicio creadas por el ADM, aunque ciertamente son más fáciles de implementar (ya que requieren relativamente poca reflexión y tienen muchos puntos de interfaz descentralizados) probablemente crearán problemas en el futuro cuando sea el momento de modificar un sistema en vivo y en crecimiento.

Debo agregar también que no todos los casos requieren un modelo de dominio (y mucho menos el ADM). A veces es mejor utilizar un estilo más procedimental / funcional de la tarea que se basa en datos y no depende de las reglas de negocio / lógica de toda la aplicación.

Si está tratando de decidir los pros y los contras de una aplicación completa, creo que es importante diseñar primero cómo se vería cada una para su aplicación determinada ANTES de comenzar a escribir una sola línea de código. Una vez que haya CRC o estructurado su aplicación en ambos estilos, dé un paso atrás y decida cuál tiene más sentido y se adapta mejor a la aplicación.

También piense en cuál será más fácil de mantener ...

Peter M. Elias
fuente
1

Da una mejor previsibilidad. A los gerentes les gusta eso, especialmente si el proyecto es tiempo y materiales pagados. Cada cambio significa mucho trabajo, por lo que el trabajo difícil puede esconderse detrás de mucho trabajo repetitivo. En un sistema DRY bien diseñado, la previsibilidad es muy mala, ya que constantemente está haciendo cosas nuevas.

Stephan Eggermont
fuente
1

Después de leer por primera vez el libro de Eric Evans sobre el diseño impulsado por dominios, realmente no entendí que no se trata solo de un montón de patrones tácticos para diseñar buenas clases de modelos de dominio.

Después de aprender más sobre el tema y usar los patrones estratégicos también, finalmente comencé a comprender que al principio se trata de obtener una comprensión profunda de los problemas comerciales que está tratando de resolver.

Y solo después de eso, puede decidir qué partes del sistema encajarán para aplicar patrones tácticos como agregados, entidades , repositorios, etc. junto con los llamados modelos de dominio rico (a diferencia de los anémicos ). Pero para beneficiarse de estos patrones, tiene que haber suficiente complejidad con respecto a la lógica empresarial para esa parte del sistema.

Entonces, cuando se trata de implementar la solución al problema en cuestión, primero se debe determinar si este problema específico se aborda mejor con un enfoque basado en CRUD o invirtiendo en un modelo de dominio rico junto con los patrones tácticos mencionados.

Si CRUD tiene más sentido, por ejemplo, si no hay una lógica de negocios compleja y la mayor parte de la lógica está relacionada con la transformación, transferencia y persistencia de datos, la implementación de un modelo de dominio puede ser una exageración innecesaria. Esto no significa que no habrá mucho trabajo por hacer, sino simplemente que no son las reglas de negocio las que producen el mayor esfuerzo de implementación. Pero en este caso no existe un modelo de dominio anémico , simplemente porque no existe ningún modelo de dominio . Lo que preferirá ver son cosas como DTO (objetos de transferencia de datos) o DAO(Objetos de acceso a datos) y clases de servicio que operarán en los datos. Y las operaciones correspondientes se relacionan en gran medida con la transformación de datos de una representación a otra y con la transferencia de datos con muy poca o casi ninguna lógica empresarial.

Si determinó que hay una gran cantidad de lógica empresarial compleja que también cambiará con el tiempo, invertir en un modelo de dominio es, según mi experiencia, una buena idea. La razón es que es más fácil representar la perspectiva empresarial mediante código y facilitar la comprensión de las operaciones correspondientes que reflejan el dominio empresarial y sus reglas. Esto no significa que tenga que haber clases de modelo de dominio en cada caso de uso. Por ejemplo, si no hay un estado para mutar y persistir, también puede haber solo servicios de dominio que contengan la lógica del dominio y se implementen más como funciones puras.

Pero si también hay un estado para mutar y persistir que también tiene un propósito y significado en el dominio empresarial, el estado y el comportamiento que cambia este estado deben encapsularse . Con eso, nadie puede eludir las reglas comerciales tan fácilmente y, por lo tanto, conducir a estados inválidos junto con fallas graves. Los llamados modelos de dominio anémicos a menudo son fuentes de tales problemas . Este suele ser el caso si ve un código donde diferentes componentes operan en la misma clase de modelo de dominio "anémico" verificando alguna parte de su estado y cambiando alguna parte de su estado sin preocuparse o conocer las invariantes generales de esa entidad comercial. No es necesario llamar a esto un anti-patrón, pero es importante entender que, pierde muchos beneficios de los modelos de dominio enriquecidosen un enfoque basado en DDD junto con los problemas mencionados. Cuando se usa un modelo de dominio donde el comportamiento y sus datos se colocan en la misma clase, también puede haber muchos "clientes" diferentes que llaman a operaciones de esa clase, pero no necesitan preocuparse de que los invariantes comerciales de la entidad comercial se adhieran como la clase de modelo de dominio siempre se encargará de eso y también puede informar al "cliente" sobre operaciones no válidas o incluso lanzar excepciones como red de seguridad.

En resumen , creo que es importante no confundir las clases de estructura de datos (como DTO o DAO) con clases de modelo de dominio anémico . En un enfoque basado en CRUD elegido de manera cuidadosa e intencional, no hay ninguna ventaja en tratar de utilizar un modelo de dominio porque hay una lógica empresarial demasiado menos compleja.

Por modelo de dominio anémico, me referiría al código a partir del cual puedo ver que hay una gran cantidad de lógica y reglas comerciales complejas que se distribuyen en diferentes componentes que deberían estar más cerca de los datos que esta lógica está cambiando.

También hay otra lección que aprendí a lo largo del camino: si intentas usar el mismo lenguaje comercial (también conocido como el lenguaje ubicuo ) en tu código que los dueños de bistecs están usando en su vida laboral diaria, ya obtendrás muchas ventajas en cuanto a la comprensión de el dominio empresarial y mejorar la legibilidad de su código que le ayudará mucho sin importar si utiliza un enfoque basado en CRUD o modelo de dominio.

afh
fuente
0

Para extender la respuesta de Michael, habría pensado que está (bastante) claro dónde debería ir ese código: en un Mediador dedicado que maneja la interacción entre la Orden y el Inventario.

Desde mi punto de vista, la clave del dominio es que DEBE contener el comportamiento de prueba simple, los isInThisState()métodos, etc. En mi experiencia, estos también están esparcidos por las lágrimas del servicio (sic :)) en la mayoría de las empresas, y se copian o se reescriben sin cesar. Todo lo cual rompe las reglas estándar de adhesión.

En mi opinión, el enfoque debería ser apuntar a un DM que mantenga tanto del comportamiento empresarial como sea práctico, colocar el resto en áreas claramente designadas (es decir, no en los servicios)

Luz de tira
fuente
Lo que pasa con un Mediador es que hay muy poca diferencia entre eso y la programación procedimental de todos modos; solo está agrupando algunas funciones que no pertenecen a ninguno de los objetos. El hecho de que los agrupe en otro objeto no hace mucha diferencia.
Rob Grant
0

Mi equipo prefiere personalmente el ADM. tenemos un conjunto de objetos comerciales que representan partes específicas de nuestro dominio. Usamos servicios para guardar estos objetos en la base de datos. Nuestros objetos comerciales tienen métodos, sin embargo, estos métodos solo manipulan su estado interno.

El beneficio para nosotros de usar ADM sobre RDM se puede ver en cómo mantenemos los objetos en db. Los desarrolladores que trabajan en nuestros sistemas de código heredados pueden usar nuestros objetos comerciales (del nuevo sistema) y continuar usando su capa de acceso a datos actual para conservar estos objetos en la base de datos. El uso de RDM obligaría a los desarrolladores de nuestro sistema heredado a inyectar objetos de Repositorio en nuestro modelo comercial ... lo que no sería consistente con su capa de acceso a datos actual.

caa
fuente
-15

Un modelo de dominio anémico es un antipatrón. Los antipatrones no tienen ventajas.

andreas buykx
fuente
10
Estoy en desacuerdo. La mayoría de los antipatrones tienen estuches de esquina en los que son una mejor solución que otras alternativas.
Bill Karwin
19
Los anti-patrones tienen ventajas. Por eso la gente los usa, aunque generalmente son malas ideas.
Kristopher Johnson
6
Replicar que algo es un anti-patrón como un hecho cuando es solo una opinión (incluso si es algo del calibre de Fowler), esa no es una forma válida de responder.
luis.espinal
@luis: Justo lo que estaba a punto de escribir antes de verte comentar. Además, existen herramientas para cumplir un propósito. Si Fowler no quiere llamarlo OO, está bien. Pero eso no indica automáticamente una mala solución / arquitectura / etc.
JensG