driven domain ddd context domain-driven-design repository-pattern ddd-repositories

domain-driven-design - domain - ddd context



¿Está bien que las entidades accedan a los repositorios? (5)

Acabo de empezar a trabajar con DDD, así que tal vez esta es una pregunta tonta ...

¿Está bien que una entidad acceda a un repositorio (a través de una interfaz IRepository) para obtener un valor en tiempo de ejecución? Por ejemplo, quiero aplicar una selección "predeterminada" para una propiedad:

class Person { private Company _employer; public Company Employer { get { return _employer; } set { if(value != null) { _employer = value; } else { _employer = employerRepository.GetDefaultEmployer(); } } } ... }

Mi pregunta es si hacer algo como esto es una violación horrible de los principios DDD. Y si no es así, mi siguiente pregunta sería ¿cuál es la mejor manera de proporcionar el repositorio para usar? ¿Debería suministrarse cuando se crea el objeto Persona?

Gracias p


¿Es realmente lo que se recomienda hacer ddd?

¿Y qué pasa si no tiene un repositorio en memoria, sino una base de datos relacional para su repositorio y desea obtener 1000 personas con su empleador? ¿Vas a hacer 1000 consultas a través de la llamada de EmployerRepository ...?

Utilizaría NHibernate o cualquier ORM para ayudar a implementar personRepository. Con NHibernate, utilizaré Hibernate Query cerca de este: "from Person join fetch Employer" que cargará una instancia "Employer" en cada instancia de "Person", con solo una consulta SQL.

¿Es una violación a DDD?


Antes que nada, creo que la entidad en sí misma y cómo ensamblar la entidad son 2 deberes de hecho. Entonces, idealmente, es mejor distribuirlos en diferentes clases. Pero eso depende de también.


Creo que es fácil decir que una entidad no debería estar al tanto de los repositorios, sino difícil de poner en práctica. Especialmente cuando un agregado obtiene una gran colección de vo dentro de él, tenemos que refactorizarlo y delegar operaciones como agregar a algún servicio de dominio que realmente actúe como un repositorio para evitar la sobrecarga de cargar toda la colección en la memoria.
Pero no creo que sea razonable que las entidades conozcan los repositorios. Si tenemos que hacerlo, entonces usemos servicios de dominio en su lugar. También deberíamos considerar si un repositorio viola el principio de responsabilidad única : debería haber sido considerado como una colección de raíces agregadas, no como una fábrica normal.


La respuesta tipo a usted es el estándar. Depende .

Como regla general, nunca hagas esto. Mantenga sus entidades sin referencias a repositorios. [ poner el sombrero práctico ] En algunos casos raros y extremadamente raros en los que tiene una razón muy, muy, muy buena para hacer esto, agregue un gran comentario que explique por qué lo hace y hágalo: agregue la referencia o use el despacho doble para aprobar el repositorio [ sombrero apagado ]

Además, si desea seguir los principios DDD, se recomienda encarecidamente que tenga acceso a un experto de dominio y a un proceso iterativo de desarrollo (vea Eric Evans, lo que aprendí desde el libro ).

Con su experto en dominios debe definir contextos delimitadores y lo más importante, los agregados y sus raíces agregadas y sus entidades y objetos de valor. Bajar por el camino de DDD no es fácil al principio, pero las palabras clave están desbordadas.

Algunas cosas con respecto al código que publicaste:

  1. No se recomienda tener instaladores públicos en sus entidades. Use métodos que expresen mejor la intención.

  2. Si se crea una instancia de persona sin inicializar el campo _employer, el getter para la propiedad del Empleador devolverá nulo. Si luego establece el valor de la propiedad del Empleador en nulo, la próxima llamada al captador devolverá un valor no nulo. Esto es probablemente inesperado por los usuarios de su clase.

  3. La persona que llama configurando al Empleador de la Persona (ya sea por public setter o por método público) debe conocer la instancia exacta de la Compañía que debe establecer, incluso si es la predeterminada. Tal vez la persona que llama puede tener la referencia al repositorio.

  4. Dependiendo de su dominio concreto, la Compañía podría ser un objeto de valor. En ese caso, en lugar de inicializar el _empleador con nulo, podría inicializarlo con el valor predeterminado para el objeto de valor. Este podría ser el caso si solo tienes muy pocas compañías (1-2) y son inmutables y no tienen un comportamiento específico.


no es una violación horrible de DDD es una horrible violación de ... bueno ... es simplemente horrible (digo esta lengua en la mejilla) :).

En primer lugar, su entidad se vuelve dependiente de tener un repositorio ... eso no es ideal. Lo ideal sería que tu repositorio creara la Persona y luego le asignaras todo lo que necesita para ser efectivo en el contexto actual del dominio.

Entonces, cuando necesite una Persona, irá personRepository.GetPersonWithDefaultEmployer () y recuperará a una persona que tiene un empleador predeterminado poblado. El personRepository tendrá una dependencia en un repositorio de empleador y lo usará para poblar a la persona antes de devolverla.

PersonReposotory : IPersonRepository { private readonly IEmployerRepository employerRepository; //use constructor injection to populate the EmployerRepository public PersonRepository(IEmployerRepository employerRepository) { this.employerRepository = employerRepository; } public person GetPersonWithDefaultEmployer(int personId) { Person person = GetPerson(personId); person.Employer = employerRepository.GetDefaultEmployer(personId); return person; } }