Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Domain driven design 是否允许我拥有;“不完整”;DDD中的总量?_Domain Driven Design - Fatal编程技术网

Domain driven design 是否允许我拥有;“不完整”;DDD中的总量?

Domain driven design 是否允许我拥有;“不完整”;DDD中的总量?,domain-driven-design,Domain Driven Design,DDD声明您只能通过实体的聚合根访问实体。比如说,你有一个聚合根X,它可能有很多子Y实体。现在,对于某些场景,您一次只关心这些Y实体的一个子集(可能在分页列表中显示它们) 那么,是否可以实现一个存储库,以便在这种情况下返回一个不完整的聚合?例如,一个X对象的集合只包含我们感兴趣的Y实例,而不是全部?例如,这可能会导致X上执行某些涉及Ys的计算的方法的行为不符合预期 这是否表明所讨论的Y实体应被视为提升为聚合根 我目前的想法(在C#)是利用LINQ的延迟执行,这样我的X对象就有一个IQueryab

DDD声明您只能通过实体的聚合根访问实体。比如说,你有一个聚合根X,它可能有很多子Y实体。现在,对于某些场景,您一次只关心这些Y实体的一个子集(可能在分页列表中显示它们)

那么,是否可以实现一个存储库,以便在这种情况下返回一个不完整的聚合?例如,一个X对象的集合只包含我们感兴趣的Y实例,而不是全部?例如,这可能会导致X上执行某些涉及Ys的计算的方法的行为不符合预期

这是否表明所讨论的Y实体应被视为提升为聚合根

我目前的想法(在C#)是利用LINQ的延迟执行,这样我的X对象就有一个IQueryable来表示它与Y的关系。这样,我就可以通过过滤实现透明的延迟加载。。。但是要让它与ORM(在我的例子中是Linq到Sql)一起工作可能有点棘手


还有其他聪明的想法吗?

你真的在问两个重叠的问题

  • 题目和问题的前半部分是哲学/理论性的。我认为仅通过实体的“聚合根”访问实体的原因是为了抽象掉您所描述的各种实现细节。通过聚合根进行访问是一种通过拥有受信任的访问点来降低复杂性的方法。你通过遵守惯例来消除摩擦/歧义/不确定性。不管它在根目录中如何实现,您只知道当您请求一个实体时,它将在那里。我不认为这种观点排除了您所描述的“过滤存储库”。但要为开发人员提供一个可供使用的实例,在不明确其“Filteredity”的情况下,不可能实例化存储库;同样,如果可以共享对存储库实例的访问,则在调用程序中编码时,“Filteredity”应该是明确的

  • 问题的后半部分是关于在特定平台上的实现。我不知道你为什么提到延迟执行,我认为这与过滤问题是正交的。使用LINQ实现过滤本身可能有点棘手。也许您不需要内联Where lambda,而是设置它们的集合,并根据需要的过滤器选择一个


  • 我认为有很多子实体的聚合根是代码气味,或者DDD气味,如果你愿意的话。一般来说,我有两种选择

  • 将聚合拆分为许多较小的聚合。这意味着我的原始设计不是最优的,我需要确定一些新的实体
  • 将域拆分为多个有界上下文。这意味着存在使用聚合中实体的公共子集的特定场景集,而存在使用不同子集的其他场景集

  • 吉米·尼尔森(Jimmy Nilsson)在他的书中暗示,与其阅读一个完整的集合,不如阅读其中部分的快照。但您不能将快照类中的更改保存到数据库中

    第6章:准备基础设施-查询。第226页


    您是被允许的,因为代码无论如何都会编译,但是如果您要进行纯DDD设计,则不应该有不完整的对象实例

    如果您害怕加载一个只使用其子实体的一小部分的大型对象,那么您应该研究LazyLoading

    LazyLoading延迟加载您决定延迟加载的内容,直到它们被访问的那一刻。一旦代码调用它们,它们就利用回调调用加载方法

    那么,是否可以实现存储库,以便在这种情况下 返回不完整的聚合


    一点也不。聚合是更改系统状态的跨国边界。切勿使用聚合查询数据。将系统分为写侧和读侧。(阅读有关CQR和CQR的信息)。当我们认为基于“CRUD”时,我们基于一些资源来实现我们的系统。假设您有“约会”合计。认为“粗糙”意味着我们应该实现用例创建、更新、删除、获取所有约会。这意味着应该为GetAll返回约会[]。当您认为基于用例(六边形体系结构)时,您的用例将是ScheduleAppointment、RescheduleAppointment、CancelAppointment。但对于查询端,它可以是:/myCalendar。我们返回ClientCalendar对象中特定用户的所有约会。为查询端创建单独的DTO。千万不要将聚合用于此目的。

    这可能是一种代码气味,但也可能不是。我也有同样的问题。我有一个跟踪类,它保存地理航路点。现在,该跟踪可以任意延长,而跟踪本身是一个实体,而航路点则不是。它们是有价值的对象。因此,如果我想在纯DDD意义上更新跟踪,我必须加载完整的聚合根跟踪及其所有航路点,添加一些航路点,然后再次存储完整的跟踪。这显然不适用于大型记录道。因此,由于性能问题,我可能会允许部分加载聚合根…我意识到这个答案已经有11年历史了。。。但我相信,人们应该根据领域专家的说法对它们的总量进行建模。因此,如果有人误解了领域专家所说的话,那么应该将一个巨大的集合重新建模为更小的集合,以更好地匹配领域专家的愿景。在这种情况下,一个巨大的聚合与领域专家的心智模型是一致的——从形式上讲,DDD要求它是巨大的。我想是运气不好吧。实际上,Eric Evans在一次演讲中提到了这个问题和可能的解决方案: