DDD总边界一至一些并不是一个许多实体之间在一个集合体

0

的问题

我看过一教程有关DDD在其它说,如果我必须根聚集SnackMachine其中有30多儿童要素的儿童的要素,应在单独的集合体。 例如,SnackMachine有很多PurshaseLog(超过30),这是更好地为PurshaseLog可以在一个单独的集合体。 为什么?

2
2

因为限制性的总体大小的聚集是因为你总是载的全部聚集到的记忆,你总是储存完整的集合体的事务. 一个非常大的聚合会引起的技术问题。

这就是说,没有这种"30孩子元件"中的规则集合体的设计和它的声音,任意作为一项规则。 例如,具有较少的非常大的孩子的元素可以在技术上比具有30很轻的儿童的要素。 一个很好的方式存储的聚集是为计文件,因为你总是会读和写的文件为原子操作。 如果你认为它这样,你会意识到,一个总的设计,意味着一个非常大或甚至日益增长的儿童收集最终将导致问题。 一PurhaseLog听起来像是一个不断增长的收集。

第二部分的规定说"把它放在一个单独聚集"也是不正确的。 你不创造的聚集,因为你需要储存一些数据,并且它不适合进入一个现有的集合体。 你创建的聚集,因为你需要执行一些业务逻辑和业务逻辑将需要一些数据,所以你把东西放在一起,在一个集合体。

因此,尽管你怎么解释你的问题是需要考虑的事项时,设计的聚集体,以避免具有技术问题,我会建议你把你的关注的实际责任的集合体。

在你的实例中,什么是责任的SnackMachine? 它是否真的需要(全部)的清单的PurchaseLogs? 什么样的行动将SnackMachine露? 让我们说,它暴露了PurchaseProduct(productId)和LoadProduct(productId、数量). 来执行其业务的逻辑,这个集合体将需要一个产品清单和保持计数的可用量,但它不需要储存的采购记录。 相反,在每次购买的,它可以发布一份事件ProductPurchased(SnackMachineId,ProductId、日期、AvailableQuantity). 然后外部系统可以订阅这一事件。 一个用户可以登记录,无法购买请登录于报告目的,另一用户可以派人来重新装载机时的股票低于X。

2021-11-17 23:29:06
2

如果录,无法购买请登录不是其自己的总那么它意味着它只能被检索或加入的一部分作为儿童收集的SnackMachine.

因此,每次你想添加一个录,无法购买请登录的,你会检索SnackMachine与其子PurchaseLogs,增加录,无法购买请登录其收集。 然后节省更改单元的工作。

你真的需要检索30+购买日志,这是冗余为目的使用的情况下创建一个新的采购记录?

应用层级备选方案1(录,无法购买请登录是一个有实体的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();

应用层级备选方案2(录,无法购买请登录是根聚集)

// 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()

录,无法购买请登录-备选案文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;
    }
}

第二种选择下的轮廓的使用情况的更多精确和结果也在很多小i/o的数据库。

2021-11-18 13:22:33

其他语言

此页面有其他语言版本

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