DDD los límites de Agregado algunos y no de uno a muchos entre las entidades en un agregado

0

Pregunta

He visto un tutorial acerca de DDD en el que se dice que si tengo agregado raíz SnackMachine que tiene más de 30 elementos secundarios que el niño los elementos deben estar en separar el agregado. Por ejemplo, SnackMachine tiene un montón de PurshaseLog (más de 30) y es mejor para el PurshaseLog ser separado en un agregado. ¿Por qué es eso?

2
2

La razón para limitar el tamaño total de un agregado es porque siempre se carga el agregado completo en la memoria y te guarde siempre el agregado completo transaccionalmente. Un gran agregado causaría problemas técnicos.

Dicho esto, no hay tal "30 elementos secundarios" de la regla en el agregado de diseño y suena arbitraria como una regla. Por ejemplo, tener menos muy grande de elementos secundarios podría ser técnicamente peor que tener el 30 de muy poquito de los elementos secundarios. Una buena forma de almacenamiento de los agregados es como json documentos, dado que siempre vas a leer y escribir documentos como operaciones atómicas. Si usted piensa de esta manera, usted va a darse cuenta de que un agregado de diseño que implica un muy elevado o creciente colección infantil, podría causar problemas. Un PurhaseLog suena como una colección cada vez mayor.

La segunda parte de la regla que dice "poner en una nueva agregado" tampoco es correcto. Usted no cree agregados debido a que usted necesita para almacenar algunos datos y no encaja en ninguna de las agregada. Crear agregados, porque es necesario implementar algunos lógica de negocio y de esta lógica de negocio se necesitan algunos datos, por lo que poner las dos cosas juntas en un agregado.

Así que, a pesar de lo que explicas en tu pregunta son cosas a tener en cuenta a la hora de diseñar los agregados para evitar tener problemas tecnológicos, yo sugeriría que usted ponga su atención a las responsabilidades actuales de los agregados.

En tu ejemplo, ¿cuáles son las responsabilidades de la SnackMachine? ¿Realmente necesita el (completo) lista de PurchaseLogs? Lo que las operaciones de la SnackMachine exponer? Digamos que expone PurchaseProduct(idproducto) y LoadProduct(idproducto, cantidad). Para ejecutar su lógica de negocio, este agregado necesitaría una lista de los productos y mantener un recuento de su cantidad disponible, pero no se deben guardar la compra de registro. En su lugar, en cada Compra, podría publicar un evento ProductPurchased(SnackMachineId, Idproducto, Fecha, AvailableQuantity). Luego de sistemas externos podría suscribirse a este evento. Un suscriptor podría registrar el PurchaseLog a efectos de notificación, y otro suscriptor puede enviar a alguien para volver a cargar la máquina cuando la población era menor que X.

2021-11-17 23:29:06
2

Si PurchaseLog no es su propio agregado, a continuación, implica que sólo puede ser recuperada o agregado como parte de la colección infantil de SnackMachine.

Por lo tanto, cada vez que desee agregar un PurchaseLog, tendría que recuperar el SnackMachine con su hijo PurchaseLogs, agregar el PurchaseLog a su colección. A continuación, guardar los cambios en su unidad de trabajo.

¿Usted realmente necesita para recuperar 30+ compra de los registros que son redundantes para el propósito del caso de uso de creación de un nuevo registro de compra?

Capa de aplicación - Opción 1 (PurchaseLog es una entidad estatal de SnackMachine)

// Retrieve the snack machine from repo, along with child purchase logs
// Assuming 30 logs, this would retrieve 31 entities from the database that
// your unit of work will start tracking.
SnackMachine snackMachine = await _snackMachineRepository.GetByIdAsync(snackMachineId);

// Ask snack machine to add a new purchase log to its collection
snackMachine.AddPurchaseLog(date, quantity);

// Update
await _unitOfWork.SaveChangesAsync();

Capa de aplicación - Opción 2 (PurchaseLog es un agregado de la raíz)

// Get a snackmachine from the repo to make sure that one exists
// for the provided id.  (Only 1 entity retrieved);
SnackMachine snackMachine = await _snackMachineRepository.GetByIdAsync(snackMachineId);

// Create Purhcase log
PurchaseLog purchaseLog = new(
   snackMachine,
   date,
   quantity);

await _purchaseLogRepository.AddAsync(purchaseLog);

await _unitOfWork.SaveChangesAsync()

PurchaseLog - opción 2

class PurchaseLog
{
    int _snackMachineId;
    DateTimne _date;
    int _quantity;

    PurchaseLog(
        SnackMachine snackMachine,
        DateTime date,
        int quantity)
    {
        _snackMachineId = snackMachine?.Id ?? throw new ArgumentNullException(nameof(snackMachine));
        _date = date;
        _quantity = quantity;
    }
}

La segunda opción sigue los contornos de su caso de uso más precisa y también los resultados en mucho menos de e/s con la base de datos.

2021-11-18 13:22:33

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................