usa unidad trabajo repositorio que patrón patron parte para net modelo implementación framework diseño abstracto orm domain-driven-design repository-pattern unit-of-work domain-model

orm - que - Uso práctico de la unidad de trabajo y patrones de repositorio.



patron repositorio laravel (3)

¡Buena pregunta!

Depende de cuáles sean tus límites de trabajo. Si van a abarcar varios repositorios, es posible que tenga que crear otra abstracción para asegurarse de que se cubren varios repositorios. Sería como una pequeña capa de "servicio" que se define en Diseño impulsado por dominio.

Si su unidad de trabajo va a ser más o menos por repositorio, entonces me gustaría ir con la segunda opción.

Sin embargo, mi pregunta sería: ¿cómo puede preocuparse por el repositorio cuando escribe un ORM? Los consumidores de su Unidad de trabajo los definirán y utilizarán, ¿no? Si es así, no tiene más opción que solo proporcionar una Unidad de trabajo y sus consumidores tendrán que alistar los repositorios con su unidad de trabajo y también serán responsables de controlar los límites de la unidad de trabajo. ¿No es así?

Estoy construyendo un ORM y trato de averiguar cuáles son las responsabilidades exactas de cada patrón. Digamos que quiero transferir dinero entre dos cuentas, utilizando la Unidad de Trabajo para administrar las actualizaciones en una sola transacción de base de datos. ¿Es correcto el siguiente enfoque?

  1. Consíguelos en el repositorio
  2. Adjuntarlos a mi Unidad de Trabajo
  3. ¿Se compromete la transacción comercial?

Ejemplo:

from = acccountRepository.find(fromAccountId); to = accountRepository.find(toAccountId); unitOfWork.attach(from); unitOfWork.attach(to); unitOfWork.begin(); from.withdraw(amount); to.deposit(amount); unitOfWork.commit();

En caso de que, como en este ejemplo, la Unidad de trabajo y el Repositorio se utilicen de forma independiente, o:

  • ¿Debería la Unidad de Trabajo usar internamente un Repositorio y tener la capacidad de cargar objetos?
  • ... ¿o debería el Repositorio usar internamente una Unidad de Trabajo y adjuntar automáticamente cualquier entidad cargada?

Todos los comentarios son bienvenidos!


La respuesta corta sería que el Repositorio estaría utilizando el UoW de alguna manera, pero creo que la relación entre estos patrones es menos concreta de lo que parece inicialmente. El objetivo de la Unidad de Trabajo es crear una manera de agrupar esencialmente un grupo de funciones relacionadas con la base de datos para que puedan ejecutarse como una unidad atómica. A menudo hay una relación entre los límites creados cuando se usa UoW y los límites creados por las transacciones, pero esta relación es más una coincidencia.

El patrón Repository, por otro lado, es una forma de crear una abstracción que se asemeja a una colección sobre una raíz agregada. La mayoría de las veces, el tipo de cosas que se ven en un repositorio están relacionadas con la consulta o la búsqueda de instancias de la raíz agregada. Una pregunta más interesante (y una que no tiene una sola respuesta) es si tiene sentido agregar métodos que se ocupen de algo distinto a la consulta de agregados. Por un lado, podría haber algunos casos válidos en los que tenga operaciones que se aplicarían a varios agregados. Por otro lado, se podría argumentar que si está realizando operaciones en más de un Agregado, en realidad está realizando una sola acción en otro Agregado. Si solo está consultando datos, no sé si realmente necesita crear los límites implícitos en el UoW. Todo se reduce al dominio y cómo se modela.

Los dos patrones se manejan a niveles de abstracción muy diferentes, y la participación de la Unidad de Trabajo dependerá de cómo se modelan los Agregados. Los Agregados pueden querer delegar el trabajo relacionado con la persistencia a las Entidades que administra, o podría haber otra capa de abstracción entre los Agregados y el ORM real. Si sus Agregados / Entidades están lidiando con la persistencia, entonces puede ser apropiado que los Repositorios también gestionen esa persistencia. Si no, no tiene sentido incluir UoW ​​en su Repositorio.

Si desea crear algo para el consumo público en general fuera de su organización, le sugeriría que cree sus interfaces de repositorio / implementaciones base de manera que les permita interactuar directamente con su ORM o no, según las necesidades del usuario. de su ORM. Si esto es interno, y usted está haciendo el trabajo de persistencia en sus Entidades de agregados, entonces tiene sentido que su Repositorio haga uso de su UoW. Para un Repositorio genérico tendría sentido proporcionar acceso al objeto UoW desde implementaciones del Repositorio que pueda asegurarse de que esté inicializado y desechado adecuadamente. En esa nota, también habrá ocasiones en las que es probable que desee utilizar múltiples Repositorios dentro de lo que sería un solo límite UoW, por lo que desearía poder pasar una UoW ya preparada al Repositorio en ese caso.


Te recomiendo que uses el enfoque cuando el repositorio usa UoW internamente. Este enfoque tiene algunas ventajas, especialmente para la aplicación web.

En la aplicación web, el patrón recomendado de uso de UoW es Unidad de trabajo (sesión) por solicitud HTTP. Entonces, si sus repositorios compartirán UoW, podrá usar el caché de primer nivel (usando el mapa de identidad) para el objeto solicitado por otros repositorios (como los diccionarios de datos a los que se hace referencia en múltiples agregados). Además, tendrá que confirmar solo una transacción en lugar de múltiples, por lo que funcionará mucho mejor en términos de rendimiento.

Puede echar un vistazo a los códigos fuente de Hibernate / NHibernate que son ORM maduros en el mundo Java / .NET.