Inyección de modelos de dominio anémico y servicios de dominio

19

El modelo de dominio anémico se describe como un anti-patrón en el diseño de dominio impulsado por Martin Fowler. Para tener una lógica de negocios en los modelos de dominio, a menudo se utilizan servicios de dominio. Pero inyectar servicios de dominio en modelos de dominio es considerado perjudicial por Vaughn Vernon (ver "Implementación de diseño impulsado por dominio, página 387).

En mi opinión, esas opiniones son contradictorias, ¿es esto cierto? ¿Cómo se pueden considerar ambos puntos?

¿Es realmente un modelo de dominio rico con servicios de dominio inyectados versus modelo de dominio anémico y servicios de dominio normales ?

Sjoerd222888
fuente
44
De ninguna manera soy un experto en esto, pero pensé que el tipo de lógica que entraba en los servicios de dominio y en las entidades de dominio era fundamentalmente diferente. La lógica que entra en las entidades es la lógica necesaria para mantener el objeto en un estado correcto. Esto implica validación y lógica de transformación. Los servicios de dominio, por otro lado, son para lógica de nivel superior. Entonces, por ejemplo, un servicio de dominio modelaría un proceso de negocio que involucra múltiples tipos diferentes de entidades de formas complejas.
MetaFight
2
@MetaFight: incluso si un proceso de negocios afecta a múltiples entidades de manera compleja, puede lograr esto sin servicios, dado un buen modelo de dominio de Agregado de Raíz, es decir, un modelo de dominio que tiene acceso a todas las entidades afectadas como propiedades o campos en sí mismo.
Greg Burghardt
Eso tiene sentido :)
MetaFight

Respuestas:

16

Un modelo anémico es simplemente un contenedor de datos. No contiene comportamiento. (Esto podría considerarse algo bueno en el paradigma funcional). Lo contrario de un modelo anémico no es un modelo inyectado lleno de servicios de dominio. Estás describiendo dos extremos: ambos son malos.

Si tiene un modelo anémico, no está aceptando completamente lo que ofrece OOP. Si comienza a inyectar servicios en esos modelos, es probable que esté inyectando preocupaciones que no pertenecen allí. O eso o tu modelo es más anémico de lo que piensas. ¿Por qué más necesitarías el servicio además de que proporciona algo que se requiere pero falta? (Perder puede significar anémica).

Evitar ambos "avisos" conduce a un diseño más fuerte. ¿Tiene algo en un servicio que un modelo necesita? Tal vez debería trasladarse al modelo. Si no, tal vez debería reconsiderar sus preocupaciones. El comportamiento de un modelo debería funcionar dentro del modelo. Principalmente (si no solo) debe preocuparse por los miembros. Pero recuerde, todavía habrá cosas que funcionen en o con el modelo. Por ejemplo, los modelos no deberían abrir conexiones TCP o escuchar eventos de UI, incluso si de alguna manera están involucrados. Eso es responsabilidad de otra persona y que alguien no pertenece dentro del modelo.

Roger escaso
fuente
77
Una buena distinción que me gusta recordar es que su Modelo de Dominio implementa la lógica de negocios, y sus Servicios de Dominio ejecutan la lógica de negocios en los Modelos de Dominio. La diferencia es quién llama a quién. Los servicios pueden llamar a los métodos del Modelo de dominio. Si los modelos de dominio están llamando a métodos de servicio, ha volteado el patrón sobre su cabeza.
Greg Burghardt
7

No es contradictorio. Ambos proponentes desean que coloque su código real en el objeto de dominio mismo.

es decir.

public class Order
{
    private string status = "not bought";
    public void Buy()
    {
        this.status = "bought";
    }
}

vs ADM

public class Order
{
    public string Status = "not bought";
}

public class BuyingService
{
    public Order Buy(Order order)
    {
         Order o = new Order();
         o.status = "bought";
         return o;
    }
}

vs servicios inyectados

public class Order
{
    public Order(IBuyingService bs)
    {
        _bs = bs;
    }
    private IbuyingService _bs;
    private string status = "not bought";
    public void Buy()
    {
        this.status = _bs.Buy();
    }
}

public class BuyingService : IBuyingService
{
    public string Buy()
    {
         return = "bought";
    }
}

Francamente, cada enfoque tiene ventajas y desventajas. El que elija es en gran medida una cuestión de preferencia personal

Ewan
fuente