asp.net-mvc - net - mosh hamedani repository pattern
Patrón de repositorio vs DAL (11)
Definitivamente no eres el que confunde las cosas. :-)
Creo que la respuesta a la pregunta depende de qué tan purista quieras ser.
Si quieres un punto de vista DDD estricto, eso te llevará por un camino. Si nos fijamos en el repositorio como un patrón que nos ha ayudado a estandarizar la interfaz de la capa que separa los servicios de la base de datos, lo llevará a otro.
Desde mi punto de vista, el repositorio es solo una capa de acceso a los datos claramente especificada. O, en otras palabras, una forma estandarizada de implementar su Capa de acceso a los datos. Existen algunas diferencias entre las diferentes implementaciones de repositorio, pero el concepto es el mismo.
Algunas personas pondrán más restricciones DDD en el repositorio mientras que otras utilizarán el repositorio como un mediador conveniente entre la base de datos y la capa de servicio. Un repositorio como un DAL aísla la capa de servicio de los datos específicos de acceso.
Un problema de implementación que parece hacerlos diferentes, es que a menudo se crea un repositorio con métodos que toman una especificación. El repositorio devolverá datos que satisfagan esa especificación. La mayoría de los DAL tradicionales que he visto tendrán un mayor conjunto de métodos donde el método tomará cualquier cantidad de parámetros. Si bien esto puede sonar como una pequeña diferencia, es un gran problema cuando ingresas a los reinos de Linq y Expressions. Nuestra interfaz de repositorio predeterminada se ve así:
public interface IRepository : IDisposable
{
T[] GetAll<T>();
T[] GetAll<T>(Expression<Func<T, bool>> filter);
T GetSingle<T>(Expression<Func<T, bool>> filter);
T GetSingle<T>(Expression<Func<T, bool>> filter, List<Expression<Func<T, object>>> subSelectors);
void Delete<T>(T entity);
void Add<T>(T entity);
int SaveChanges();
DbTransaction BeginTransaction();
}
¿Es esto un DAL o un repositorio? En este caso, supongo que es ambos.
Kim
¿Son la misma cosa? Acabo de terminar de ver el tutorial Storefront de Rob Connery y parecen ser técnicas similares. Quiero decir, cuando implemento un objeto DAL tengo los métodos GetStuff, Add / Delete etc. y siempre escribo la interfaz primero para poder cambiar db más tarde.
¿Estoy confundiendo cosas?
El repositorio es un patrón, esta es una forma de implementar las cosas de manera estandarizada para reutilizar el código como podamos.
En el repositorio de mundo externo (es decir, código de cliente) es el mismo que DAL, excepto:
(1) es insertar / actualizar / eliminar métodos está restringido a tener el objeto contenedor de datos como el parámetro.
(2) para la operación de lectura puede tomar una especificación simple como un DAL (por ejemplo, GetByPK) o una especificación avanzada.
Internamente, funciona con una capa de mapeador de datos (por ejemplo, contexto de marco de entidad, etc.) para realizar la operación CRUD real.
Qué patrón de repositorio no significa: -
Además, he visto personas a menudo confundirse al tener un método Save diferente como la implementación de ejemplo de patrón de repositorio además de los métodos Insert / Update / Delete que compromete todos los cambios en memoria realizados por los métodos de inserción / actualización / eliminación a la base de datos. Podemos tener un método Save definitivamente en un repositorio, pero eso no es responsabilidad del repositorio para aislar CUD en memoria (Crear, Actualizar, Eliminar) y métodos de persistencia (que realiza la operación de escritura / cambio en la base de datos), pero el responsabilidad del patrón de la Unidad de Trabajo.
¡Espero que esto ayude!
Entonces, en la mayoría de los casos (simples) DAO es una implementación de Repository?
Por lo que yo entiendo, parece que DAO trata precisamente con el acceso db (CRUD - ¿Sin embargo, no selecciona?) Mientras que el Repositorio le permite abstraer todo el acceso a datos, quizás siendo una fachada para múltiples DAO (tal vez diferentes fuentes de datos).
¿Estoy en el camino correcto?
Estaba buscando una respuesta a una pregunta similar y estoy de acuerdo con las dos respuestas mejor clasificadas. Al tratar de aclarar esto por mí mismo, descubrí que si las Especificaciones, que van de la mano con el patrón del Repositorio, se implementan como miembros de primera clase del modelo de dominio, entonces puedo
- reutilizar definiciones de especificación con diferentes parámetros,
- manipular los parámetros de las instancias de especificación existentes (por ejemplo, para especializar),
- combinarlos ,
- realizar lógica de negocios en ellos sin tener que acceder a ninguna base de datos,
- y, por supuesto, probarlos en unidades independientes de las implementaciones reales del Repositorio.
Incluso puedo ir tan lejos y afirmar que a menos que el patrón Repositorio se use junto con el patrón de Especificación, no es realmente "Repositorio", sino un DAL. Un ejemplo artificial en pseudo-código:
specification100 = new AccountHasMoreOrdersThan(100)
specification200 = new AccountHasMoreOrdersThan(200)
assert that specification200.isSpecialCaseOf(specification100)
specificationAge = new AccountIsOlderThan(''2000-01-01'')
combinedSpec = new CompositeSpecification(
SpecificationOperator.And, specification200, specificationAge)
for each account in Repository<Account>.GetAllSatisfying(combinedSpec)
assert that account.Created < ''2000-01-01''
assert that account.Orders.Count > 200
Consulte el Ensayo de especificación de Fowler para obtener más detalles (en eso basé lo anterior).
Un DAL tendría métodos especializados como
IoCManager.InstanceFor<IAccountDAO>()
.GetAccountsWithAtLeastOrdersAndCreatedBefore(200, ''2000-01-01'')
Puede ver cómo esto puede volverse engorroso rápidamente, especialmente dado que tiene que definir cada una de las interfaces DAL / DAO con este enfoque e implementar el método de consulta DAL.
En .NET, las consultas LINQ pueden ser una forma de implementar especificaciones, pero la combinación de Especificación (expresiones) puede no ser tan fluida como con una solución interna. Algunas ideas para eso se describen en esta pregunta SO .
La ventaja de usar un patrón de repositorio es burlarse de su capa de acceso a los datos, para que pueda probar el código de su capa de negocios sin llamar al código DAL. Hay otras grandes ventajas, pero esto parece ser muy vital para mí.
Mi opinión personal es que todo se trata de mapeo, ver: http://www.martinfowler.com/eaaCatalog/repository.html . Entonces, la salida / entrada del repositorio son objetos de dominio, que en el DAL podrían ser cualquier cosa. Para mí esa es una adición / restricción importante, ya que puede agregar una implementación de repositorio para una base de datos / servicio / lo que sea con un diseño diferente, y tiene un lugar claro para concentrarse en hacer el mapeo. Si no usa esa restricción y tiene el mapeo en otra parte, entonces tener diferentes formas de representar datos puede afectar el código en lugares que no deberían estar cambiando.
Por lo que entiendo, pueden significar básicamente lo mismo, pero el nombre varía según el contexto.
Por ejemplo, puede tener una clase Dal / Dao que implemente una interfaz IRepository.
Dal / Dao es un término de capa de datos; los niveles más altos de su aplicación piensan en términos de repositorios.
Se trata de interpretación y contexto. Pueden ser muy similares o de hecho muy diferentes, pero mientras la solución haga el trabajo, ¡qué hay en un nombre!
Un repositorio es un patrón que se puede aplicar de muchas maneras diferentes, mientras que la capa de acceso a datos tiene una responsabilidad muy clara: el DAL debe saber cómo conectarse a su almacenamiento de datos para realizar operaciones CRUD.
Un repositorio puede ser un DAL, pero también puede sentarse frente al DAL y actuar como un puente entre la capa de objeto de negocio y la capa de datos. La implementación que se usa va a variar de un proyecto a otro.
Una gran diferencia es que un DAO es una forma genérica de lidiar con la persistencia de cualquier entidad en su dominio. Un repositorio, por otro lado, solo trata con raíces agregadas.