2010-11-11 12 views
18

¿Cómo se relacionan Services y Repositories entre sí en DDD? Quiero decir, he estado leyendo sobre DDD durante los últimos 2 días y en todos lados, siempre hay una capa Service y siempre hay una capa Repository. ¿Cómo se diferencian o se complementan?Servicios y repositorios en DDD (C#)

Por lo que he leído, ¿no es Repository la capa responsable de delegar las interacciones entre la aplicación y los datos?

Así que, ¿cuál es la necesidad de que la capa Service si se tiene que poner en práctica el Repository para interactuar con los datos de todos modos a pesar de que la Repository probablemente ya implementa los métodos necesarios para hacerlo?

Agradeceré algunas aclaraciones sobre el tema.

P.S. No sé si esto ayudará, pero estoy trabajando con una aplicación ASP.NET MVC 2 en la que estoy tratando de implementar el patrón Repositorio. Acabo de terminar la ejecución del patrón de inyección de dependencia (por primera vez en la historia) ...

ACTUALIZACIÓN

bien, con tantas respuestas, creo que entiendo cuál es la diferencia. Por lo tanto, para revisar (corríjanme si me equivoco):

  • Una capa Repository interactúa sólo con un único objeto fuera de la base de datos o el ORM, IEmployeeRepository ->Employee.

  • A Service capa encapsula la funcionalidad más compleja en los objetos devueltos desde Repositories, ya sea uno o varios.

Entonces, entonces tengo una pregunta secundaria. ¿Se considera una mala práctica crear objetos abstractos para enviar a mis puntos de vista? Por ejemplo, un AEmployee (A para abstract porque para mí I significa interface) que contiene propiedades de Employee y X o X?

En realidad, una sub-demanda más. Si una capa Service se puede considerar "sintonizada" para una aplicación, ¿necesita implementarse con una interfaz?

+1

Creo que los servicios pueden agregar varios repositorios. –

+0

Existe una gran discrepancia entre el uso común/popular de Repository y Service (el uso que se encuentra en muchos ejemplos y tutoriales) y cómo Domain Driven Design los define. Creo que es importante entender las diferencias. –

+1

@Sergey tiene razón: debe haber un repositorio por raíz agregada, pero un servicio puede (y funcionará) en múltiples reposiciones, hecho posible por el patrón de la unidad de trabajo. y, por cierto, ¿cuántas veces se puede hacer una pregunta como esta? hay muchas preguntas sobre esto en el desbordamiento de pila. – RPM1984

Respuesta

16

Es cierto que un repositorio funciona con datos (es decir, SQL, servicio web, etc.) pero ese es el único trabajo. Operaciones CRUD, nada más. No hay lugar para la lógica de busines basada en procedimientos almacenados.

El servicio (o capa de lógica de negocios) proporciona la funcionalidad. Cómo para completar una solicitud de negocio (es decir.calcular el salario), qué tienes que hacer.

Ah, y este es un muy buen libro DDD: http://www.infoq.com/minibooks/domain-driven-design-quickly

+0

Con usted completamente excepto que no puede llamar a los procesos almacenados. ¿Por qué no? Si puede devolver datos de una vista, ¿por qué no devuelve datos de un procedimiento almacenado? –

+1

¿Esto supone que no hay procedimientos almacenados? Si tiene procedimientos almacenados, ¿dónde está el código de llamada si no está en el repositorio? No estoy de acuerdo con que el patrón de repositorio excluya la lógica comercial en los procedimientos almacenados. El repositorio encapsula todas las interacciones de la base de datos, tanto CRUD como los procedimientos almacenados. –

+0

@ Michael Shimmins: Creo que no es una buena práctica dividir la lógica de negocios en pedazos. Si tengo una capa de negocios, debería hospedar allí toda mi lógica de dominio. Por supuesto que tengo procedimientos almacenados 'inteligentes' también, es decir. para informes rápidos. Pero sp no tiene nada que ver con la lógica empresarial. Al menos en DDD. – boj

4

Por lo que recuerdo, el repositorio es la clase final antes de los datos. La clase de servicio puede actuar sobre los datos recuperados del repositorio. El repositorio realmente solo tiene la intención de obtener datos para que otra persona haga el trabajo. La capa de servicio puede proporcionar elementos tales como la lógica comercial por la que deben pasar todos los datos. También podría proporcionar una traducción entre la lógica de la aplicación y la capa de datos. Pero, nuevamente, esto es solo lo que puedo recordar.

3

no hay un estándar de oro que define un servicio o un repositorio. En mis aplicaciones, un repositorio es (como usted dice) una interfaz en una base de datos. Un servicio tiene acceso completo a un repositorio, pero el servicio expone un subconjunto de funcionalidades a sus consumidores.

Piense en el repositorio como de un nivel más bajo. El repositorio debe exponer muchas formas de acceder a la base de datos subyacente. Un servicio puede combinar llamadas a un repositorio con otro código que solo tiene sentido a nivel de código (es decir, no en la base de datos), como el acceso a otro estado en la aplicación o validación/lógica comercial que no se puede aplicar fácilmente en una base de datos

21

El Servicio utilizará un Repositorio para recuperar una Entidad y luego invocará métodos en ella (la Entidad) para realizar el Comando/tarea.

+3

+1: tanta información en pocas palabras ... – Mayo

10

Como ejemplo concreto una aplicación de Compras podría tener los siguientes servicios:

ShoppingCartService - maneja un carro de artículos con añadir/quitar la actualización de soporte/etc

OrderService - tomar una carro, lo convierte en un pedido y maneja el proceso de pago, etc.

cada uno de estos servicios necesita hablar una "fuente de datos" para las operaciones CRUD. Aquí es donde el patrón Repository es útil ya que abstrae la carga y el guardado de datos hacia y desde la fuente de datos, ya sea una base de datos, un servicio web o incluso un caché en memoria.

Cuando desee crear un prototipo rápido de su aplicación sin tener que ocuparse de la configuración de la base de datos, el esquema, los procedimientos almacenados, los permisos, etc., puede crear una memoria caché o repositorio falso en cuestión de minutos.

Para el ejemplo anterior de su prototipo podría comenzar con lo siguiente:

  • FakeCustomerRepository
  • FakeAddressRepository
  • FakeCartRepository
  • FakeCartLineItemRepository
  • FakeOrderRepository
  • FakeOrderLineItemRepository

una vez que su prototipo está listo para evolucionar al siguiente nivel se puede poner en práctica estas en contra de una base de datos real:

  • SQLCustomerRepository
  • SQLAddressRepository
  • SQLCartRepository
  • SQLCartLineItemRepository
  • SQLOrderRepository
  • SQLOrderLineItemRepository
+0

De algunos ejemplos que he visto habría una biblioteca de clases Project.Repository y una biblioteca de clases Project.Service para albergar las clases que mencionaste anteriormente. Normalmente también veo una biblioteca de clase Project.Model. ¿Dónde colocas las interfaces para las clases de repositorio en Project.Model? – Billy

+0

Normalmente tengo un repositorio y una carpeta de modelos dentro de mi proyecto Project.Service. Luego tengo/Repository/Interfaces,/Repository/FakeRepository,/Repository/SQLRepository,/Models,/Service/Interfaces,/Service/[implementation classes]. Normalmente, no comparto repositorios en todos los servicios porque mis repositorios están diseñados específicamente para los modelos dentro de ese servicio. –