Cuando utilicé IoC Container en mi último proyecto, terminé con entidades anémicas y la mayor parte de mi lógica de negocios en Servicios sin estado.
He visto proyectos escritos por otros desarrolladores que utilizan "Inversión de control" y siempre están "anémicos".
Dado que el "Modelo de dominio anémico" es antipatrón, ¿es posible usar IoC y Rich Domain? ¿Son buenos ejemplos, proyectos de código abierto que hacen eso?
dependency-injection
Mag20
fuente
fuente
Respuestas:
Para empezar: DI e IoC no son sinónimos. Lo siento, pero debo señalarlo (me parece que crees que lo son).
En cuanto a su consulta ... Bueno, la inyección de dependencia es solo una herramienta. Cómo va a utilizar esta herramienta es algo completamente diferente. También hay otras herramientas (patrones de diseño) que podrían agregarse al problema. Por ejemplo, creo que la adopción generalizada del patrón MVC es uno de los ingredientes clave para formar el antipatrón del modelo de dominio anémico: los controladores (en aplicaciones más simples, en aplicaciones más complicadas que serían una capa de servicio adicional) asumen la responsabilidad de validar las reglas comerciales , imponiéndolos y transformando las entidades de base de datos en algo útil, mientras que Business Layer se convierte en simple Data Access Layer que es ORM simple con mapeo uno a uno a entidades de bases de datos.
Ciertamente, así es cómo diseña su aplicación: puede crear un modelo de dominio correcto si lo desea, y todos estos IoC, DI, MVC no lo detienen. Lo que podría detenerte es tu equipo. De alguna manera, debe convencerlos de que usen el camino correcto y puede ser difícil ya que muchos desarrolladores de software no tienen una sólida formación arquitectónica.
fuente
La mayoría de las aplicaciones (si no todas) son una combinación de problemas de infraestructura y dominio. Cuando alcance un cierto nivel de complejidad, facilitará la administración si el dominio está separado de la infraestructura, de modo que sea más fácil razonar y evolucionar independientemente.
Por supuesto, el modelo de dominio aún necesita comunicarse con el resto del sistema y generalmente será con servicios sin estado (que son parte del dominio) que tienen problemas de infraestructura (como el acceso a la base de datos) inyectados en ellos. El uso de un contenedor de IoC no elimina esta dependencia, mueve su configuración a un área separada, lo que nuevamente hace que sea más fácil razonar y mantener.
Las entidades almacenan el estado y deben ser responsables de las reglas comerciales. Si sus servicios hacen cumplir todas las invariantes y otras reglas comerciales, entonces es probable que la lógica esté en el lugar equivocado.
Ahora, si tiene la lógica en los lugares correctos y aún así ha terminado con servicios que no son más que envoltorios alrededor de cosas de infraestructura y entidades que son solo bolsas de propiedades, entonces es muy probable que el dominio no sea lo suficientemente complejo como para justificar la sobrecarga de su propio modelo. Casi cualquier cosa que lea sobre DDD contendrá un descargo de responsabilidad que en realidad solo está destinado a dominios complejos, pero parece que esto se olvida con demasiada frecuencia.
fuente
Ve a la fuente. Comience con la pieza de Fowler en modelos de dominio anémico . Hace referencia al diseño impulsado por dominio de Eric Evan como un ejemplo de buena práctica. El código fuente para eso está aquí . Descargalo.
Observe que usa la Inversión de control (busque @Autowired), y tiene clases de servicio (BookingService) y clases de "proceso de negocio" (por ejemplo, ItineraryUpdater).
El artículo original de Fowler comienza el camino hacia el ejemplo que está buscando.
fuente
VoyageRepositoryHibernate
clase, que se colocó en la capa de infraestructura pero que en realidad depende de la capa de dominio.save(foo)
con código que está sujeto a cambios cuando cambia el modelo de dominio (por ejemplo, si se agrega un nuevo atributoMyDomainObject
), entonces (por definición) debe pertenecer a la capa de dominio; de lo contrario, ya no se puede hablar de tener "capas".Supongo que te refieres a DI en lugar de IoC, y el proyecto en el que trabajaste usa un contenedor DI como Spring. IoC tiene dos sabores principales: DI y patrón de localización. No veo por qué el patrón Localizador debería ser un problema, así que centrémonos en DI.
No creo que sea posible, o al menos sería muy poco práctico. El aspecto principal de los contenedores DI es que controlan la creación de objetos cuando los inyectan en otros ("objetos administrados"). El conjunto de objetos administrados que está vivo cuando se ejecutan los proyectos es independiente de los elementos de dominio que existen en su proyecto, pero depende de cómo están conectados los objetos y qué ámbitos (singleton, prototipo) se les asignan.
Es por eso que no desea permitir que el contenedor DI administre sus objetos de dominio. Pero si crea objetos manualmente (con nuevo), no puede inyectar otros objetos a sus objetos de dominio. (Dejando a un lado las posibles soluciones alternativas con el cableado manual). Dado que necesita estas inyecciones para reemplazar las implementaciones con otras, no puede reemplazar la funcionalidad de los objetos de dominio enriquecido con DI. Por lo tanto, no querrá colocar la funcionalidad en objetos de dominio, o perderá las características de la DI.
No veo cómo podría funcionar un contenedor DI hipotético que no administra sus objetos, y ninguna de las implementaciones existentes lo permite. Por lo tanto, es justo afirmar que DI se basa en la gestión de objetos. Por lo tanto, siempre tendrá la tentación de dividir los objetos potenciales de Rich Domain en una clase anémica y una o varias clases de script de transacción.
fuente