Estoy confundido acerca de los enfoques de diseño impulsado por el dominio. De las fuentes en la red, entendí que es una forma de segregar sus objetos de Domain Objects de Database Objects de datos, pero no entiendo la diferencia entre dos.
Para un ejemplo, tomemos el código del ejemplo de Encuestas en el tutorial de django, hay dos modelos Polls y Choice .
¿Son estos objetos de domain level objects de database level objects de datos?
¿Existe la necesidad de DDD con un ORM?
En caso afirmativo, ¿puede proporcionar una buena situación en la que necesite utilizar el enfoque DDD con un ORM?
por ejemplo este es el modelo
class Polls(models.Model): question = models.CharField(max_length=200) pub_date = models.DateTimeField('date published')Código de enfoque DDD que he visto escribir a personas
class PollService(object): def __init__(self, poll_repository): self.poll_respository = poll_respository def update(self, poll_id): poll = self.poll_respository.fetch_by_id(poll_id) poll.question += '?' self.poll_respository.update(poll) #assume that the following code works? class PollRepository(): def __init__(self, db): self.db = db def update(self, poll): try: self.db.session().add(poll) self.db.session.commit() except Exception: self.db.session.rollback() ¿Es este un enfoque correcto? Veo mucho código redundante aquí, pero la gente dice que las Polls son un objeto de nivel de dominio y que no deberían comunicarse directamente con la base de datos.
¿DDD siempre viene con un repositorio DDD? Por qué necesitamos un repositorio DDD si tenemos un ORM
Otro enfoque
views.py def update_poll(poll_id): poll = models.Polls.objects.get(poll_id) poll.question += '?' poll.save()¿Qué tiene de malo este enfoque?
Django está diseñado para el uso de Active Record Pattern como se describe en esta página de Filosofía de diseño de Django .
Su segundo ejemplo sigue este patrón: el modelo en sí tiene sus propiedades, comportamiento y acceso a datos contenidos dentro.
Todavía puede usar este patrón de una manera más similar a DDD, si empuja más comportamiento en el modelo. por ejemplo, en su ejemplo, un uso más efectivo del patrón sería envolver la línea
poll.question += '?' en un método de revelación de intenciones en el objeto de encuesta, de modo que el método update_poll sea:
views.py def update_poll(poll_id): poll = models.Polls.objects.get(poll_id) poll.add_question() poll.save() Esto tiene la ventaja de separar la lógica empresarial (introducida en el modelo) de la lógica de flujo de la aplicación (el método update_poll )
Aunque sugeriría usar un nombre que realmente ilustre la intención o el propósito del método en lugar de simplemente agregar_pregunta.
Pero incluso si hace esto, todavía está usando el patrón Active Record, no DDD puro.
DDD y un ORM están intentando resolver diferentes problemas. Los ORM brindan una forma conveniente de abstraer el mundo de las bases de datos orientado a registros similar a un conjunto de una manera más orientada a objetos.
DDD es un enfoque para ayudar a modelar situaciones complejas del mundo real en el código.
Muchos sistemas DDD usan ORM para resolver las preocupaciones de infraestructura de recuperación y persistencia de la base de datos (a veces envolviendo el ORM en un repositorio por una variedad de razones), pero el enfoque de DDD está en los modelos de dominio y qué tan adecuadamente modelan el dominio bajo consideración. .
Entonces, en su ejemplo, los beneficios de DDD son difíciles de ver, ya que la lógica comercial es relativamente simple.
Recomiendo leer la fuente autorizada en DDD - Domain Driven Design de Eric Evans para obtener una descripción general independiente del idioma del enfoque y las situaciones en las que agrega valor.
Usted pregunta:
¿Puede actualizarme con un buen ejemplo en el que tiene sentido usar DDD con un ORM?
y
Si usamos ORM, creo que no hay necesidad de un repositorio DDD
Creo que una mejor manera de pensarlo es: cuando se usa un ORM, el ORM es el repositorio. Le pides un modelo y te devuelve un modelo. Ese es el propósito de un repositorio. Cuando las personas lo envuelven en una clase llamada "repositorio", generalmente es porque quieren hacer una de estas cosas:
Esta descripción general del patrón del repositorio proporciona otra buena descripción del patrón del repositorio ddd.
Paul Hallett lo reunió todo en su hermoso y completo artículo: https://phalt.github.io/post/django-api-domains
Y el ejemplo aquí: https://github.com/phalt/django-api-domains
En breve:
La guía de estilo de Django es antigua.
La documentación, desde los tutoriales hasta los documentos completos, habla de un mundo de modelo-vista-controlador en el que Django representa HTML y lo entrega a un navegador web.
Algo sobre esto me pareció extraño: he trabajado con Django desde 2012 y solo recuerdo haberlo usado para renderizar HTML una vez. Casi todo mi tiempo con Django, y todo el tiempo que he visto que se habla de Django en conferencias, ha sido para proporcionar una API (generalmente con Django REST Framework) para un proyecto frontend. Yo diría que este es en realidad el estándar de facto para Django hoy. La documentación está desactualizada para los casos de uso populares actuales. Esta es generalmente una tendencia que estoy viendo con Django: el proyecto está tratando de modernizar la forma en que se ejecuta e incluso cómo manejar la sincronización correctamente. ¿Tal vez es hora de que Django reconsidere los patrones de diseño que sugiere para los desarrolladores también?
Volviendo a mi problema inmediato: para ayudar al equipo a organizar mejor su software, me propuse encontrar una buena guía de estilo de la comunidad. Leí sobre la renuncia impulsada por el dominio, los beneficios de los contextos acotados, y encontré una buena guía de estilo de Hacksoft que intentamos usar. ¡Esto fue genial! La documentación aquí fue muy sólida y perfecta para proyectos más pequeños o pequeñas empresas.
Pero durante nuestra experimentación con él, descubrimos que no era adecuado para su propósito por varias razones. Es decir, el hecho de que se aliente la lógica empresarial a vivir en los modelos. Django también recomienda esto y es básicamente el patrón de registro activo. Según nuestra experiencia con equipos muy grandes, mantener la lógica empresarial vinculada a los modelos animó a los desarrolladores a llenar models.py con toneladas de código. Esto hace que sea muy difícil para los desarrolladores trabajar en un archivo al mismo tiempo. Sin mencionar el hecho de que cuando un solo archivo posee más de un problema en un dominio (presentación, datos, controlador, etc.) tiende a absorber también todos los demás problemas en el archivo.
Si necesita algunos ejemplos sobre DDD y Django, estas https://dry-python.org/static/slides/ddd-toolkit-2.html diapositivas que utilizan herramientas de Python seco podrían ser útiles.
Además, consulte el proyecto de ejemplo https://github.com/dry-python/tutorials/tree/master/django/example