Bueno, puede ver un buen ejemplo en Spring Data Framework que se basa en el concepto de repositorios.
Allí verá que los repositorios solo se ocupan del almacén de datos y rara vez contienen lógica empresarial (esto está reservado para la capa de servicio). Entonces, por ejemplo, si observa su diseño, verá que tienen una interfaz CRUDRepository que expone métodos para crear, destruir y recuperar entidades (entre otras cosas). También hay un PagingAndSortingRepository que agrega funcionalidad adicional para precisamente eso, ordenar y buscar resultados, etc.
Entonces, este marco es quizás un buen lugar para estudiar un buen diseño de repositorio.
Hasta donde yo sé, muchos de los conceptos implementados por Spring Data Framework provienen de un gran libro llamado Diseño impulsado por dominio: abordar la complejidad en el corazón del software , el libro tiene una sección completa dedicada al diseño de repositorio.
Puede considerar obtener una copia del mismo.
Un pequeño extracto del libro explica:
El patrón REPOSITORY es un marco conceptual simple para encapsular esas soluciones y recuperar el enfoque de nuestro modelo.
Un REPOSITORIO representa todos los objetos de cierto tipo como un conjunto conceptual (generalmente emulado). Actúa como una colección, excepto con una capacidad de consulta más elaborada. Se agregan y eliminan objetos del tipo apropiado, y la maquinaria detrás del REPOSITORIO los inserta o los elimina de la base de datos. Esta definición reúne un conjunto coherente de responsabilidades para proporcionar acceso a las raíces de AGREGADOS desde el ciclo de vida temprano hasta el final.
Los clientes solicitan objetos del REPOSITORIO utilizando métodos de consulta que seleccionan objetos basados en criterios especificados por el cliente, generalmente el valor de ciertos atributos. El REPOSITORIO recupera el objeto solicitado, encapsulando la maquinaria de consultas de bases de datos y mapeo de metadatos. Los REPOSITORIOS pueden implementar una variedad de consultas que seleccionan objetos en función de los criterios que requiera el cliente. También pueden devolver información resumida, como un recuento de cuántas instancias cumplen algunos criterios. Incluso pueden devolver cálculos de resumen, como el total de todos los objetos coincidentes de algún atributo numérico.
Un REPOSITORIO le quita una gran carga al cliente, que ahora puede hablar con una interfaz simple y reveladora de intenciones, y preguntar qué necesita en términos del modelo. Para soportar todo esto se requiere una gran cantidad de infraestructura técnica compleja, pero la interfaz es simple y está conceptualmente conectada al modelo de dominio.
Por lo tanto:
Para cada tipo de objeto que necesita acceso global, cree un objeto que pueda proporcionar la ilusión de una colección en memoria de todos los objetos de ese tipo. Configure el acceso a través de una interfaz global bien conocida.
Proporcione métodos para agregar y eliminar objetos, que encapsularán la inserción o eliminación real de datos en el almacén de datos. Proporcione métodos que seleccionen objetos en función de algunos criterios y devuelvan objetos o colecciones de objetos completamente instanciados cuyos valores de atributo cumplan con los criterios, encapsulando así el almacenamiento real y la tecnología de consulta. Proporcione REPOSITORIOS solo para raíces AGREGADAS que realmente necesitan acceso directo. Mantenga al cliente enfocado en el modelo, delegando todo el almacenamiento de objetos y el acceso a los REPOSITORIOS.