¿Pueden los clientes llamar a métodos en entidades que no sean la raíz agregada?

7

Evans introduce en su libro "Diseño impulsado por dominio" en el Capítulo 6 "Agregados" el concepto de agregados. Además, define las reglas para traducir ese concepto en una implementación (Evans 2009, pp. 128-129):

  

La ENTIDAD raíz puede entregar referencias a las ENTIDADES internas de otros objetos, pero esos objetos pueden usarlas solo de forma transitoria y es posible que no se adhieran a la referencia.

Después de elaborar otras reglas, las resume en este párrafo:

  

Agrupe las entidades y los objetos de valor en agregados y   Define límites alrededor de cada uno. Elija una entidad para ser la raíz   de cada Agregado, y controlar todo el acceso a los objetos dentro   El límite a través de la raíz. Permitir objetos externos para sostener   Referencias solo a la raíz. Referencias transitorias a internas   Los miembros pueden ser distribuidos para su uso dentro de una sola operación.   solo. Debido a que la raíz controla el acceso, no puede ser anulada por   Cambios en los internos. Este arreglo hace que sea práctico   hacer cumplir todos los invariantes para los objetos en el Agregado y para el   Agregado como un todo en cualquier cambio de estado.

Entonces, ¿qué significa exactamente el uso transitorio?

Mi colega entiende que solo la raíz agregada expone una interfaz pública para los clientes. Los clientes no tendrán la oportunidad de llamar a ninguna operación en una entidad que no sea la raíz agregada.

Mi comprensión de las oraciones citadas es diferente. Entiendo que, de hecho, permite explícitamente a los clientes realizar operaciones de llamadas en entidades internas. Sin embargo, solo después de obtenerlos de la raíz.

Así que vamos a tener un ejemplo concreto:

Digamos que un Cart consiste en muchos Items . Cada Item tiene un Quantity . El modelo debe admitir el caso de uso "Aumentar la cantidad de un artículo específico". No se pueden violar invariantes que afecten a nada fuera del Artículo.

¿Un modelo infringe las reglas citadas anteriormente, cuando un cliente puede hacer esto llamando a cart.item(itemId).increaseQuantity() o debería permitirse que un cliente solo llame a cart.increaseItemQuantity(itemId) ? ¿Cuál sería el beneficio de este último?

    
pregunta Markus Malkusch 18.08.2016 - 21:26

1 respuesta

2

Mientras que Item no pueda existir sin que también esté presente Cart , entonces no hay diferencia entre las dos opciones. Es posible mantener invariantes en ambos casos.

En el caso de que el método esté en Item , Item puede "notificar" a su carro primario para verificar el invariante cuando necesita cambiar su propio estado. Esto hace que las cosas sean un poco más complicadas, porque entonces existe una dependencia cíclica entre Item y Cart (lo que supongo que no es un problema gracias a la suposición en la primera oración y algo que la OMI debe existir de cualquier manera).

En el caso de que el método esté en Cart , lo hace más simple, porque no es necesario que Item haga referencia a Cart . Pero lo hace complicado porque ahora el método no solo busca invariables y cambia el estado. Pero también debe asegurarse de que el artículo (o su ID) sea válido para este Cart . En el otro caso, esto ya se maneja mediante un método que consulta un artículo dado desde el carrito.

tl; dr; Ambas opciones tienen claras ventajas y desventajas y ninguna parece ser obviamente mejor o peor que otra.

    
respondido por el Euphoric 19.08.2016 - 12:20

Lea otras preguntas en las etiquetas