2009-12-29 34 views
12

Pros:Pros y contras de DDD Repositorios

  • repositorios ocultar consultas complejas.
  • Los métodos de depósito se pueden usar como límites de transacción.
  • ORM puede ser fácilmente burlado

Contras:

  • marcos ORM ofrecen ya una colección como interfaz para objetos persistentes, ¿cuál es la intención de los repositorios. Entonces los repositorios agregan complejidad extra al sistema.
  • explosión combinatoria cuando se utilizan los métodos findBy. Estos métodos se pueden evitar con objetos de Criteria, consultas u objetos de ejemplo. Pero para hacer eso, no se necesita repositorio porque un ORM ya admite estas formas de encontrar objetos.
  • Dado que los repositorios son una colección de raíces agregadas (en el sentido de DDD), se deben crear y pasar raíces agregadas incluso si solo se modifica un objeto secundario.

Preguntas:

  • Qué pros y contras lo sabe?
  • ¿Recomendarías usar repositorios? (¿Por qué o por qué no?)
+2

ORM en contraste con repositorios realmente no tiene sentido - utiliza ORM para implementar repositorios, ¿no? –

+1

Sin respuesta definitiva. Wiki de la comunidad? –

+1

Su tercera estafa no tiene sentido. Si necesita manipular un "objeto secundario" por sí mismo, debería ser una raíz agregada. –

Respuesta

8

El punto principal de un repositorio (como en el Principio de Responsabilidad Individual) es abstraer el concepto de obtener objetos que tienen identidad. A medida que me siento más cómodo con DDD, no me ha resultado útil pensar que los repositorios se centran principalmente en la persistencia de los datos, sino como fábricas que crean instancias de objetos y persisten en su identidad.

Cuando utiliza un ORM, debe utilizar su API de la forma más limitada posible, dándose una fachada tal vez que sea específica del dominio. Entonces, independientemente de su dominio, solo vería un repositorio. El hecho de que tiene un ORM en el otro lado es un "detalle de implementación".

7

Un repositorio es realmente solo una capa de abstracción, como una interfaz. Lo usa cuando desea desacoplar su implementación de persistencia de datos (es decir, su base de datos).

Supongo que si no desea desacoplar su DAL, entonces no necesita un repositorio. Pero hay muchos beneficios al hacerlo, como la capacidad de prueba.

En cuanto a la explosión combinatoria de los métodos "Buscar": en .NET puede devolver un IQueryable en lugar de un IEnumerable, y permite que el cliente llamante ejecute una consulta Linq, en lugar de utilizar un método Find. Esto proporciona flexibilidad para el cliente, pero sacrifica la capacidad de proporcionar una interfaz comprobable bien definida. Básicamente, intercambias un conjunto de beneficios por otro.

+1

+1 al devolver un IQueryable del IRepository. Esto le permite escribir su lógica de "búsqueda" en la capa de servicio/raíz, y probar esa lógica simulando un IRepository. En cuanto a las pruebas, la capa "Repositorio" es donde trazo la línea entre Pruebas unitarias y Pruebas de integración - Escribo pruebas de Integración para mis Repos y que devuelven los registros FetchAll() adecuados para un IQueryable, y la Unidad prueba todo lo demás que tiene una lógica comercial real. – eduncan911

+0

Al menos con NHibernate debe tener en cuenta que existen grandes diferencias (el caché, la consulta de ruta se ejecuta) entre la llamada a linq .Where (a => a.id == id) y la llamada a ISession.Load (id). Puede ser útil tener una manera IQueryable de acceder a los datos, pero no intente hacer todo con ellos, tenga en cuenta que los ORM generalmente ofrecen algunas formas de realizar consultas y operaciones avanzadas. –

8

El repositorio pone en primer plano el modelo de dominio al ocultar los detalles de acceso a los datos detrás de una interfaz que se basa en un lenguaje ubicuo. Al diseñar el repositorio, se concentra en los conceptos de dominio, no en el acceso a los datos. Desde la perspectiva de DDD, usar ORM API directamente es equivalente a usar SQL directamente.

Esto es como repositorio puede ser similar en la aplicación de procesamiento de pedidos:

List<Order> myOrders = Orders.FindPending() 

Tenga en cuenta que no hay términos de acceso a datos como 'criterios' o 'consulta'. El método interno 'FindPending' puede implementarse utilizando Hibernate Criteria o HQL, pero esto no tiene nada que ver con DDD.

Explosión del método es una preocupación válida. Por ejemplo, puede terminar con varios métodos como:

Orders.FindPending() 
    Orders.FindPendingByDate(DateTime from, DateTime to) 
    Orders.FindPendingByAmount(Money amount) 
    Orders.FindShipped() 
    Orders.FindShippedOn(DateTime shippedDate) 
    etc 

Esto se puede mejorar mediante el uso del patrón de especificación. Por ejemplo, usted puede tener una clase

class PendingOrderSpecification{ 
    PendingOrderSpecification WithAmount(Money amount); 
    PendingOrderSpecification WithDate(DateTime from, DateTime to) 
    ... 
} 

Así que ese depósito se verá así:

Orders.FindSatisfying(PendingOrderSpecification pendingSpec) 
Orders.FindSatisfying(ShippedOrderSpecification shippedSpec) 

Otra opción es tener repositorio separado para los pedidos pendientes y enviados.