2012-02-20 8 views
7

Primero que nada, probablemente no haya una respuesta correcta, pero estoy seguro de que hay personas que saben más que yo y que podrán ayudar.DDD - ¿Repositorio por entidad o uno para todo?

Tengo 3 entidades: Usuario, Blog, Publicación.

El sistema puede tener cualquier cantidad de usuarios.

El usuario puede tener cualquier número de blogs, pero cada blog tiene solo un usuario.

El blog puede tener tantas publicaciones como el usuario publique, y todas las publicaciones serán del mismo usuario que posee el blog (es decir, si John posee blog Food, solo John puede publicar en este blog). Y, por supuesto, cada publicación tiene un blog para padres.

Luego tengo la página del perfil del usuario, donde quiero mostrar todos los detalles del usuario, nombres de todos sus blogs y las últimas 5 publicaciones.

Tengo una página de blog que muestra los detalles del blog, el nombre del propietario (Usuario) y los títulos de todas las publicaciones.

Luego tengo una página de publicación que muestra los detalles de la publicación, el nombre del blog y el nombre del propietario.

Como ve, tengo relaciones entre todos ellos, pero ninguno de ellos puede actuar como agregado.

No es tan difícil definir las entidades en el código, con lo que sí tengo problemas es definiendo los repositorios. ¿Cuánto necesito? 3 - uno por cada entidad? 1 - para todo? ¿Cómo realizo búsquedas?

Por ejemplo, para obtener las 5 últimas publicaciones en la página de usuario. El usuario no tiene referencia a Publicaciones, sino que contiene un contenedor de Blogs donde cada Blog contiene un contenedor de Publicaciones. ¿Debo tener un método en mi repositorio que acepte el ID de usuario y devuelva una lista de Publicaciones? O tal vez debería ser un servicio? Además, generalmente no realizo la carga de todos los datos, sino que tengo la carga lenta. Al recuperar una entidad de Usuario existente, no cargaría sus blogs a menos que sean necesarios (cuando se accede por primera vez).

Gracias de antemano.

+0

¿Qué quiere decir exactamente por 'repositorio' vs. 'servicio'? OMI esta pregunta es demasiado amplia para SO. – home

+0

Puede encontrar las definiciones aquí http://en.wikipedia.org/wiki/Domain-driven_design Y sí, tuve un poco de miedo de que la pregunta fuera demasiado amplia para SO ... –

Respuesta

4

me gustaría crear:

  • un PostRepository utiliza para manejar mensajes y comentarios
  • BlogRepository utiliza sobre todo para la búsqueda
  • UserRepository

Si no va a apoyar a los comentarios que lo haría eliminar el depósito de publicaciones y manejar publicaciones en el BlogRepository

Normalmente modelo los repositorios después de su uso y para evitar el agrupamiento de agregados (más de dos niveles).

Por ejemplo, para obtener las 5 últimas publicaciones en la página de usuario. El usuario no tiene referencia a Publicaciones, sino que contiene un contenedor de Blogs donde cada Blog contiene un contenedor de Publicaciones.

imho el usuario no debería tener un contenedor en el Blog. Tienes el repositorio para buscarlo.

¿Debo tener un método en mi repositorio que acepte el ID de usuario y devuelva una lista de Publicaciones?

sí.

¿O tal vez debería ser un servicio?

El servicio se utiliza para eliminar la lógica comercial del código que usa los modelos de dominio. No los crees hasta que obtengas ese tipo de lógica.

Además, generalmente no realizo la carga de todos los datos, sino que tengo una carga diferida. Al recuperar una entidad de Usuario existente, no cargaría sus blogs a menos que sean necesarios (cuando se accede por primera vez).

La carga diferida se puede evitar al no tener propiedades que vinculen todos los modelos de dominio. Intente solo tener propiedades para los agregados secundarios.

+0

¡Gracias por el comentario!Solución interesante, lo pensaré. Intento evitar anidar agregados también, pero no siempre es tan simple como parece. –

+0

@skwee: Lee mi actualización. – jgauffin

+0

¡Gracias que es mucho más limpio y útil! Solo tengo una pregunta: ¿por qué el usuario no debería tener el contenedor del blog? De su respuesta, simplifica claramente todo el proceso, pero no veo por qué está mal. Estoy bastante seguro de que su estado de ánimo no era algo así como "ya que tener un contenedor de blog complica la búsqueda de blogs y agrega la necesidad de implementar la carga diferida, decidiré no tener contenedor de blog en la entidad Usuario". Debería haber alguna lógica o reglas detrás de esta decisión. Me gustaría saberlo ¡Gracias! –

0

El usuario suele ser una raíz agregada típica. El agregado de usuario puede contener preferencias de usuario, estadísticas de usuario, incluso blogs.

También veo Publicar como un buen candidato para una raíz agregada con muchas cosas que gravitan alrededor de ella: Comentarios, Etiquetas, Categorías ... Luego puede usar PostRepository.LoadByBlog() o PostRepository.LoadByUser() para su páginas.

Ahora esta es solo una posibilidad inferida de lo que describió. Cada dominio es único y es posible que tengas información de cambio de juego que no conocemos.

+0

¡Gracias por tu comentario! Pero, por favor, sigamos con el dominio que describí. En el momento en que agrega otras entidades (etiquetas, categorías) el dominio cambia drásticamente, y esto no es bueno. El dominio que describí es el dominio que tengo y este es el dominio del que surgieron mis preguntas. Intencionalmente elegí un dominio relativamente simple porque no quiero complicarme (todavía no), porque por el momento carezco de la experiencia en DDD para crear dominios más complicados. –

+0

Aún así, aún tendría estas 2 raíces agregadas y los repositorios correspondientes. Suponiendo que tiene el ID de usuario como entrada (desde la URL o algo así), UserRepository.LoadById() hará el truco para mostrar los detalles del usuario. Desde allí puede navegar hasta los blogs del usuario para obtener sus títulos y PostRepository.LoadLatestFiveByUserId() le dará las 5 publicaciones más recientes. Luego puede usar PostRepository.LoadAllByBlog() y PostRepository.LoadById() para las otras páginas. – guillaume31

+0

Has adivinado correctamente sobre la URL. Soy duro con la misma solución (más o menos) pero en mi solución también tenía BlogRepository, pero luego un montón de código se duplica (es decir, BlogRepository.GetById() tendrá que cargar el blog y el usuario, mientras que UserRepository.GetById () cargará al usuario y a los Blogs para que este tipo de la misma funcionalidad se copie en 2 repositorios). –

1

Me gustaría ver la importancia de su entidad, antes de decidir si tendré un repositorio o no.

Mirando desde el lado del desarrollo basado en pruebas, tendría un repositorio para cada entidad. De esta forma puedo tener una implementación falsa de IUserRepository, IBlogPostRepository, etc. Este enfoque promueve las pruebas unitarias y me permite sustituir una implementación de repositorio por otra.

Luego, agrupaba mis repositorios en servicios como me parece adecuado. Una forma de hacerlo es escribir casos de uso y agrupar de una manera que se adapte a sus necesidades.

Por ejemplo, puedo decir que un usuario puede hacer lo siguiente:

  1. Ver publicación
  2. Presentar mensaje
  3. Editar mensaje

ahora puedo hacer una IUserService para la visión , enviando y editando publicaciones. Este servicio agregará (agrupará) mis repositorios.

Al final, podré hacer lo siguiente.

var blogPost = new BlogPost(); 
ServiceFactory.Resolve<IUserService>(c => c.SubmitPost(blogPost)); 

Ahora, esta es una forma de hacerlo.

Alternativamente, puede tener un IBlogPostService que exponga un comportamiento muy similar, o podría simplemente usar los repositorios y no implementar un servicio agregado.

punto que "estoy tratando de hacer, es que no se debe colgar en los pequeños detalles. Normalmente hay varias maneras de lograr un comportamiento similar, y la única manera de aprender es practicando.

Hacer sus repositorios son reutilizables, pero pregúntese si está sobre-ingeniería algo, es decir, ¿alguna vez voy a utilizar este repositorio por sí mismo? Una vez que tenga pocos repositorios, envuélvalos en servicio agregado.

Si su servicio tiene más de 3 repositorios (el umbral depende totalmente de usted), luego considere refaccionar este servicio en dos servicios separados.

Espero que esto ayude.

Cuestiones relacionadas