2011-09-03 37 views
15

Ésta es mi comprensión acerca de DDD en la actualidad¿Está bien omitir el patrón de repositorio para consultas complejas?

  • El patrón repositorio estricta sólo se debe aplicar get(), borrar() y crear(), y tal vez las variantes de get(), donde se puede buscar o para recuperar una colección entera
  • es común que cada raíz agregada para tener un repositorio

(desde la investigación, sé los que no se acepta universalmente normas)

La pregunta aquí es cómo implemen t consultas complejas que involucran muchas raíces agregadas. Por ejemplo, tenemos dos raíces agregadas: producto y usuario. Si estoy haciendo una página que enumera qué productos ha comprado un usuario, entonces tengo una consulta que se extiende tanto en el agregado del usuario como en el agregado del producto.

¿Cómo debe implementarse esta consulta?

  1. Lo que estoy haciendo ahora es en realidad tener un repositorio para esta consulta y consultas con funcionalidad relacionada (algunos no estarán de acuerdo y dicen que el repositorio no es una capa de consulta).

  2. Use sólo el repositorio para el producto y el usuario, agarrar todos los registros y hacer todo en la memoria (esto suena mal)

  3. Tener la consulta (LINQ o SQL) para estar dentro del servicio, no usando el repositorio asociado con los agregados en absoluto.

¿Hay alguna otra manera?

Respuesta

13

El patrón repositorio estricta sólo se debe aplicar get(), eliminar() y crear(), y tal vez las variantes de get(), donde se puede buscar o para recuperar una colección entera

La interfaz del repositorio es parte de su dominio y debe basarse en Ubiquitous Language tanto como sea posible. Todos los repositorios son diferentes al igual que todos tus agregados son diferentes. Estricto, generic repositories son sobregeneralización CRUD y pueden reducir la expresividad del código. El método 'Crear' tampoco pertenece al Repositorio porque el inicio del ciclo de vida del objeto normalmente lo maneja la Fábrica o el Objeto mismo. 'Agregar' parece un mejor nombre cuando desea persistir un objeto existente porque el Repositorio tiene una semántica de colección.

La pregunta aquí es cómo implementar consultas complejas que implica muchas raíces agregadas. Por ejemplo, tenemos dos raíces agregadas: producto y usuario .Si estoy haciendo una página que enumere los productos que un usuario ha comprado, entonces tengo una consulta que se extiende entre el agregado de usuario y el agregado del producto.

En este caso, solo tiene que escuchar los requisitos del negocio, hice hincapié en la parte que creo que es más importante. Basa en que parece que se necesita:

Products products = /* get Products repository implementation */; 
IList<Product> res = products.BoughtByUser(User user); 

La idea de organizar un código como esto es para que coincida con los requerimientos del negocio y el lenguaje en todas partes tanto como sea posible. El nombre de las interfaces del repositorio también es importante. Prefiero tener Productos o Todos los productos en lugar de ProductosRepositorio. Phil Calçado tiene un very good article sobre este tema, muy recomendable.

How should this query be implemented? 

No hay nada de especial en esta consulta, se puede implementar como todas las demás consultas en el repositorio de Productos. La consulta en sí está oculta del dominio porque la implementación del repositorio pertenece a la capa de acceso a datos. El acceso a datos puede implementar cualquier consulta porque tiene un conocimiento profundo de todos los agregados y sus relaciones. En este punto, solo sería una pregunta de Hibernate o SQL.

+1

¿A quién detras le gusta comentar? – Dmitry

+0

Me gustó más la respuesta de Szymon: fue muy sencillo en el punto en que las consultas se deben desacoplar de la capa de dominio/repositorio. – drogon

+8

Usted vota menos cuando la respuesta no es útil. ¿El mío no fue útil? – Dmitry

-5

Simplemente póngalo en una clase de repositorio. Es un Get, probablemente en el ProductRepository ya que eso es lo que está devolviendo. GetProductsByUser (int UserID). O si tiene una arquitectura n-Tier, entonces puede estar en el método de servicio.

Siempre he pensado en el repositorio como un lugar para poner cualquier método de acceso a la base de datos ya que la idea es separar el código de la base de datos de todo lo demás.

10

En primer lugar, rara vez se realizan consultas contra Aggregate Roots. Se hacen contra datos y solo devuelven datos. Los repositorios son abstracciones de persistencia muy útiles para usar en el código de capa de aplicación (comandos y tal). Los necesitamos allí porque queremos poder probar esta capa sin necesidad de una base de datos. Es por eso que cuanto menor sea el repositorio, mejor; es más fácil burlarse de él.

Tiendo a utilizar objetos especializados Finder que permiten a mi IU consultar el almacén de datos. Incluso coloco mis Buscadores en la capa UI. La cuestión es que tienden a cambiar cada vez que cambia la IU, por lo que es mejor juntarlos. Otra buena razón por la que no desea poner métodos de consulta en el repositorio es que el repositorio es parte de su dominio, su lenguaje ubicuo. No desea contaminarlos con conceptos de IU que tienden a ser de vida corta y que cambian rápidamente.

He escrito una publicación en el blog explicando este concepto hace algún tiempo. Puede encontrarlo here.

+1

+1 - Tan pronto como me di cuenta de que los datos de consulta para la interfaz de usuario y el modelo de dominio son, de hecho, dos conceptos separados, mi vida (y mi diseño) se volvieron más fáciles. ¿Por qué complicar las cosas? El modelo de dominio debe adaptarse al dominio comercial y no a los requisitos de la interfaz de usuario. – kstaruch

Cuestiones relacionadas