design - quickly - que es ddd
Diseño impulsado por dominio: raíces agregadas (3)
En el caso de un carrito de compras con un carro y artículos de línea, tengo ambos como raíces agregadas ya que a menudo los modifico de manera independiente.
public class Cart : IAggregateRoot
{
public List<LineItem> LineItems {get;}
}
public class LineItems : IAggregateRoot
{
public List<LineItem> LineItems {get;}
}
Sin embargo, tengo un contexto delimitado por separado para los pedidos y, en este caso, solo necesito tener una raíz agregada porque ya no necesito modificar las líneas de pedido de forma independiente.
public class Order : IAggregateRoot
{
public List<LineItem> LineItems {get;}
}
La otra opción es tener una forma de buscar la raíz agregada desde una identificación secundaria.
Car GetCarFromSeatID(guid seatID)
Estoy luchando con agregados y raíces agregadas. Tengo una raíz agregada natural que funciona para aproximadamente el 60% de las solicitudes de los usuarios. Es decir, esas solicitudes se aplican naturalmente a la raíz agregada.
Dentro de mi agregado, tengo otra entidad que solo puede existir como miembro de la raíz agregada. Sin embargo, a los usuarios se les informará acerca de este otro objeto de entidad. En ocasiones, tendrá sentido, conceptualmente, que los usuarios operen directamente en este objeto raíz no agregado.
Entonces, creo que tengo un par de opciones:
- Pueden ambos ser raíces agregadas dependiendo de qué operación está siendo solicitada por el usuario.
- Todas las operaciones deben pasar por la raíz agregada de nivel superior.
Tenga en cuenta que la raíz de agregado de nivel superior contendrá una colección de esta otra entidad.
Ejemplo:
Raíz de agregado principal: coche
Segunda entidad: Asiento (un auto tiene 2 o 4 asientos dependiendo del tipo). En mi dominio, los asientos solo pueden existir como parte de un automóvil.
La mayoría de las operaciones en el dominio están en el nivel de Coche. Entonces ese será un buen candidato para la raíz agregada. Sin embargo, (y estoy luchando por ejemplos aquí), algunas operaciones estarán en el nivel del asiento, por ejemplo, SpillCoffee, ChangeFabric, Clean ....
¿Can Seat y Car son raíces agregadas? ¿O debería siempre comenzar con Car?
Gracias
La idea de un agregado es garantizar la coherencia, ya que es la raíz responsable de la integridad de los datos y de forzar invariantes.
Supongamos que hay una regla como "El tejido de todos los asientos debe ser el mismo", o "solo se puede derramar café en el asiento si hay alguien dentro del automóvil". Será mucho más difícil hacer cumplir estos, una vez que los clientes estarán capaz de cambiar el tejido por separado, o estos invariantes deberán ser forzados al exterior (zona de peligro).
En mi humilde opinión, si la integridad o forzar invariantes no es un problema, entonces los agregados no son realmente necesarios. Pero, si es necesario, mi consejo es comenzar todo con el auto. Pero siempre piensa en el modelo. Si hay invariantes como estos, ¿quién aplica estas invariantes? Luego intente pasar esta idea al código, y todo debería estar bien.
Probablemente necesites un conocimiento más profundo de algún aspecto del modelo de dominio. Esta pregunta muestra que está a punto de inventar una forma de organizar las entidades para suministrar el sistema, cuando, idealmente, este tipo de preguntas ya están respondidas antes de la implementación.
Cuando esto aparece solo en la implementación del sistema, ya sea que regrese a revisar el dominio o descubrió algo de fragilidad cuyos comentarios podrían, y deberían, agregar cambios en los detalles relacionados del negocio para que el dominio sea más rico y esté mejor modelado.
En el ejemplo del automóvil, utilicé el enfoque de dos agregados que correlacionan contextos diferentes. El primero sería el enfoque de "automóvil tiene asiento", y en este agregado las posibles acciones para "asiento" serían solo las que tienen sentido para "sentarse como parte de un automóvil". Ejemplo: Limpiar
El segundo agregado estaría en el contexto de "asiento", y existirían las posibles acciones y configuraciones para el asiento como independiente. Ejemplo: ChangeFabric, ColorList. De esta manera, el "automóvil" agregado tiene "asiento", pero los clientes pueden conocer el contexto que tiene sentido. Lo cual es peligroso, como dice samuelcarrijo en la publicación anterior. Si las modificaciones entre contextos afectan la integridad del dominio, perderá todo el concepto agregado.