是否在另一个聚合根中引用另一个聚集根?
我已经完成了几年的DDD,并且在设计聚合方面仍然具有挑战性.多数民众赞成在DDD的有趣部分,这使您的头旋转.我问这个问题,因为我是一个项目的建筑师,并且我们正在设计模型.当模型与GUI并行并与客户一起聚集时,它是一种迭代. 现在解决问题.我们的情况是,我们面对的是一些成长为非常大的AR的聚集体.我认为我擅长寻找价值对象并避免贫血域模型陷阱.但是我从未去过这种情况. 一个例子是我们的系统应代表移动电信天线.天线位于绿色场上.但是天线可以带有设备的庇护所.天线可以具有微波链路,它可以在地面上有光纤线,它可以具有无线电元件,可以具有电源.面对它.如果天线被终止...所有这些依赖项也被去除.由于它们是安装的一部分(绿色场除外:)) 但是你明白了.天线模型很复杂……大型AR在并发锁,性能,记忆消耗方面是不灵活的. 阅读了沃恩·弗农(Vaughn Vernon)后,关于有效AR设计的非常好的论文 我意识到我们需要开始将大型AR切成碎片. 我的想法是像弗农(Vernon)建议这样做一样,例
4 2024-01-20
编程技术问答社区
聚合和聚合根源混淆
我被分配了一个非常简单的项目作为考试,我想到了使用域驱动的设计开发它. 你们中的许多人可能会说该应用程序是如此简单,以至于使用存储库和UOW只是浪费时间,您可能是正确的,但我认为这是一个学习更多内容的机会. 应用程序是"飞行票"系统,从以下图像中,您可能会猜测它的功能. 问题是我不确定我是否正确地分离了聚集体及其根源. 编辑: 我介绍了数据模型,以便任何人都可以轻松发现整个功能. 问题是从雇员的角度来看," rad"说的是封装整个功能,是总体根源. 但是,从管理员的角度来看,航班不是他的企业. 他只想更新或添加新的飞机公司等. 因此,有一个新的骨料根是飞机,它封装了飞机座椅(实体),seattype(value objects)和公司(实体)作为新的骨料. 这往往会使我感到困惑,因为我在另一个聚集体内有一个骨料根(飞机)(飞行汇总). 由于总体根源被认为是"核心"实体,如果没有它,它没有任何实体将没有任何意义,所以我正在考虑公司.我得出的
0 2024-01-19
编程技术问答社区
聚合根中包含的实体如何保存在DDD中?
阅读了很多帖子后,我意识到是否存在一个概念/上下文的汇总根,我们需要为整个概念/上下文都有一个存储库. 如果这样,我认为内部实体将没有任何存储库.如果是这样,这些内部实体如何保存到数据库? 我有许多内部实体.因此,想知道我是否需要在总体存储库中保存所有内部实体,它将被肿.请建议在这种情况下可以做什么. 另外,我的内部实体将在持久级别上访问其自己的每个表.如果我不允许以这种方式存储内部实体,请纠正我. 示例 认为我有一家餐厅作为总体.它可以分组一个名为评审的实体.餐厅的评论是不存在的. 在这里,如果评论是一个内部实体,并且可以对餐厅进行许多评论,则评论将保存在单独的桌子中.但是,由于只有一个餐厅存储库来供餐厅汇总,因此如何/在哪里处理储蓄评论. 解决方案 我同意其他答案中提出的一些观点,即您可能不想像这样对其进行建模,但是我认为您的问题本身尚未得到回答.例如,这很好. 所以来了: 您不会创建存储库(如DDD存储库中)对于实体而言,仅适用于
6 2024-01-19
编程技术问答社区
DDD:持久性骨料
让我们考虑典型的顺序和 OrderItem 示例.假设 OrderItem 是顺序汇总的一部分,则仅通过顺序添加它.因此,要在订单中添加新的 orderiTem ,我们必须通过存储库加载整个汇总并再次坚持整个汇总. 这似乎有很多开销.如果我们的顺序具有10 OrderItems 怎么办?这样,只是为了添加新的 orderitem ,我们不仅必须读取10 orderItems ,而且我们还应该重新插入所有这10 orderitems 再次. (这是吉米·尼尔森(Jimmy Nillson)在他的DDD书中采取的方法.每次他想持续一个总体,他都会清理所有孩子,然后再次重新插入它们.这可能会导致其他问题,因为孩子的ID是孩子的ID由于数据库中的身份列,每次都更改.) 我知道有些人可能建议将工作模式应用于汇总根部,以便跟踪已更改的内容,并且只能进行这些更改.但这违反了持久性无知(PI)原则,因为持续性逻辑正在泄漏到域模型中. 以前有人考虑过吗? mosh 解决方案
一个实体的聚合
在域驱动的设计中,如果我想使用一个存储库,我需要对其进行汇总 - 据我了解. 所以我有一个用户,它具有ID,登录,电子邮件和密码.用户是具有唯一ID的域实体. 当我想将用户添加到用户存储库时,我是否应该首先使用一个汇总根构建我的用户实体,仅此而已?在这种情况下,它看起来像是用户的代理,不需要. 或者也许我在这里错过了什么?也许用户不是实体,即使看起来像这样.也许我可以将实体直接放在存储库中? 解决方案 骨料根(ar)是一个实体,拥有自己的骨料的实体非常普遍. 您的User实体将只是一个总体.您不需要额外的具体类. 其他解决方案 在域驱动的设计中,如果我想使用一个存储库,我需要拥有 汇总 - 据我了解. 我想提出的一件重要的事情是,我们不为存储库创建聚合,而是创建存储库,因为我们需要持续汇总. 存储库处理整个聚合,仅此而已.他们保留了交易边界,这是定义您的汇总的方法. 当我想将用户添加到用户存储库时,是否应该先构建 仅以我的用户
0 2024-01-19
编程技术问答社区
每个事务多个聚合根INSTANCES
在DDD中,骨料应表示交易边界.一项需要参与多个骨料的交易通常表明应该对模型进行完善,或者应审查交易要求,或两者兼而有之. . 这意味着事务边界是每个聚合根实例还是每个聚合? 说我在每个"节点"中有一个称为" node"的聚合根,我有一个" fields(value objects)"的集合.每个"字段"是一种类型,并且可以是类型的"节点".就我而言,如果它是类型的"节点",我将将ID存储到" node"汇总root. Node (AggregateRootID 1) ---> Field1 : String (John) ---> Field2 : String (Doe) ---> Field3 : Node (AggregateRootID 2) Node (AggregateRootID 2) --> Field1 : String (Jane) --> Field2 : String (Doe) 如果我的交易更新了两个聚合实例,那是有效的吗? ,
0 2024-01-19
编程技术问答社区
骨料的根。兔子洞有多远
我正在尝试为我当前项目使用存储库模式,目前我正在尝试建模域并找到聚合根. 我已经阅读了"级联删除"规则,该规则指出,如果删除根部时删除成员是没有意义的,则不应成为根的一部分. 我将使用警察事件作为Eample: - 事件(总根) - 这可能包含调查人员,每个官员的笔记.它还可以包含嫌疑人,并列出了接受采访的日期. 该事件是否获得了CCTV录像?每次查看闭路电视的日志以及谁? 是由CCTV制作的证据/法院等 的副本 似乎所有事件都可能变得巨大,因为似乎一切都挂在那个事件上. 我的问题是双重的,总的根源应该管理多少,根部的根部是一个好主意? 这可能不是一个特别的例子,因为您可能永远不会删除像警察事件这样的事情,但我希望它能更好地描述我的问题. 解决方案 一个聚集体通常包含参考与其他聚集根.当删除包含的骨料时,应删除这些参考,但是他们指出的聚集体将保留. 使用您的类比.我们将假定仅是一个事件的一部分,并将与总体删除.没有其他汇总可以直接访问这些报
0 2024-01-19
编程技术问答社区
我应该如何加强聚合根之间的关系和约束?
我有几个问题,涉及DDD模型中两个聚合根之间的参考之间的关系.请参阅下面的典型客户/订单模型. 首先,汇总的实际对象实现之间是否始终通过ID值而不是对象引用进行参考?例如,如果我想要有关订单的客户的详细信息,我需要将客户ID带到iCustomerRepository以获取客户而不是设置订单对象以直接正确返回客户?我很困惑,因为直接返回客户似乎会使针对模型的编写代码变得更加容易,并且如果我使用Nhibernate这样的ORM,就不会难以设置代码.但是,我很确定这会违反总根/存储库之间的界限. 第二,在何处以及如何为两个汇总根部执行删除关系上的级联反应?例如,说我希望在删除客户时删除所有关联的订单. IcustomerRepository.deletecustomer()方法不应引用IorderRepostiory吗?似乎这会打破聚合/存储库之间的界限吗?我是否应该提供一个定制服务,该服务处理删除客户及其相关订单,以引用IorderRepository和IcustomerRepo
0 2024-01-19
编程技术问答社区
DDD:聚合根
我需要帮助找到我的骨料根和边界. 我有3个实体:计划,计划和计划训练.每个计划都可以包含许多计划中的和计划培训. 解决方案1:首先,我认为计划是总体根源,因为计划和计划训练在计划的上下文中没有意义.他们总是在计划之内.另外,我们有一个商业规则,说每个计划最多可以拥有3个计划的核心和5个计划培训.因此,我认为通过将计划提名为总体根源,我可以执行这个不变的. 但是,我们有一个用户搜索计划的搜索页面.结果显示了该计划本身的一些属性(且没有计划中的或计划培训).我以为如果我必须加载整个汇总,它将有很多开销.有将近3000个计划,每个计划都可能有几个孩子.将所有这些对象加载在一起,然后在搜索页面中忽略计划中心和计划培训对我来说是没有意义的. 解决方案2:我刚刚意识到用户需要2个搜索页面,他们可以在其中搜索计划的角色或计划的培训.这使我意识到他们正在尝试独立访问这些对象,并"脱离"计划的背景.因此,我以为我对最初的设计错了,这就是我提出这个解决方案的方式.因此,我认为这里有3
2 2024-01-19
编程技术问答社区
更新聚合中的实体
我正在阅读一个类似的问题:如何更新聚合中的实体,但我仍然不确定用户界面应如何与聚合中的实体进行交互. 假设我有一个User,带有一堆Address es.用户是总词根,而地址仅存在于聚合中. 在Web Inteface上,用户可以编辑他的地址.基本上,发生的是: 用户在其Web界面上看到地址列表 他点击地址,然后重定向到此页面:edit-address?user=1&address=2 在此页面上,他获得了可以修改此地址的表格. 我决定绕过汇总根,这很简单: 我们将用其Id 直接加载Address 我们会更新它,然后保存 因为我们想以DDD方式进行操作,所以我们有不同的解决方案: 我们要么要求用户通过ID 获得此地址: address = user.getAddress(id); address.setPostCode("12345"); address.setCity("New York"); em.persist(user)
0 2024-01-19
编程技术问答社区
聚合根引用其他聚合根
我目前正在与DDD一起工作很多,当从其他聚集根中加载/操作时,我正在面临问题. 对于我的模型中的每个聚合根,我也有一个存储库.存储库负责处理根的持久性操作. 假设我有两个汇总根,有一些成员(实体和价值对象). gentregatoot1和centregatoot2. gentregatoot1具有一个实体成员,该成员参考了centregatoot2. 当我加载聚合时,我也应该加载centregatoot2吗? gentregatoot2的存储库应为此负责吗? 如果是这样,gentregatoot1中的实体可以将grengregatoot2的存储库称为加载吗? 同样,当我在cotregatoot1中的实体之间建立关联到congregatoot2时,应该通过实体或通过cogtregatoot2? 来完成. 希望我的问题有意义. [edit] 当前解决方案 在 twith2sugars 的帮助下 如问题所述,骨料根可以让孩子参
0 2024-01-19
编程技术问答社区
聚集根部DDD/UoW/Repo/服务
我对存储库的聚合对象有一些疑问. 我正在使用DDD/UOW/REPO和服务模式进行休息服务.我们的新云Web应用程序将使用此服务.为了做到这一点,我们还必须从仍在生产中的旧数据库中同步数据.我们创建了一个" syncservice",该" syncservice"读取并从云到地球上读取和写入. 在我的REST/DDD-DESIGN中.而且我不希望业务逻辑运行这些逻辑,因此在原始测试项目中,我有一个用于每个模型的存储库,而端点只需进行一些简单的验证,然后使用存储库将数据直接推向数据库. 假设我有这些实体: 客户 订单 OrderLine 文章 d atabase Ressighsships : 客户可以有很多订单. 订单只能有一个客户. 订单可以具有许多订单线. 订单线可以有一篇文章. 问题: 除了文章外,所有这些聚合是吗? 以及这些实体中的哪个将具有存储库? 存储库是什么样的? 我应该为"同步服务"
跨越聚合根寻找一个孩子
存储库模式表明您只能拉出聚合根.但是,如果您不知道它是父(root),您将如何仅使用单个孩子使用uniqiue Identity(child.id)? class Parent { public int ID { get; set; } IEnumerable Children { get; private set; } } class Child { public int ID { get; private set; } public virtual Parent Parent { get; private set; } // Navigational model } 我的应用程序是无状态的(Web),为简单起见,请求仅包含孩子的ID. 我在想三种方法: 打电话给所有父母,然后礼貌地问他们谁拥有这个孩子. 在parenterrepository中有一个特殊的例程,称为GetChildById,其中有点未能使存储库的
DDD:实体在被持久化之前的身份
在域驱动的设计中,实体的定义特征之一是它具有身份. 问题: 我无法为实例创建实体提供独特的身份.仅在实体持续存在后,仅由存储库提供此身份(此值是从基础数据库提供的). 我目前无法开始使用Guid值.现有数据使用int主要键值存储,我无法生成实例化的唯一INT. 我的解决方案: 每个实体都有一个身份值 一旦持续存在(由数据库提供),身份仅设置为真实身份 当持久性之前实例化时,身份设置为默认值 如果身份默认,则实体可以通过参考 可比性 如果身份不是默认的,则实体是通过身份值可比的 代码(所有实体的抽象基类): public abstract class Entity { private readonly IdType uniqueId; public IdType Id { get { return uniqueId; }
12 2023-08-08
编程技术问答社区
只读的数据库视图如何融入资源库模式?
示例:您的数据库具有名为" CustomerorDersonhold"的SQL视图.此视图返回特定客户和订单数据字段的过滤组合.您需要在应用程序中的此视图中获取数据.如何访问此类视图符合存储库模式?您会创建一个" CustomerorDersonH​​oldRepository"?这样的仅读取视图是否被认为是骨料根? 解决方案 我更喜欢将读取存储库分开,最好甚至将其名称更改为Finder或Reader,该存储库是用于域使用的域使用,而不是用于查询仅读取数据,您可以参考我还建议将读取模型与写模型架构分开 cqrs =" http://www.udidahan.com/2009/12/09/clarified-cqrs/" rel =" noreferrer">那里 此体系结构允许您甚至在数据存储和事件采购的使用方面将读取模型与写入模型分开. 对于中间解决方案,您可以利用一些CQRS概念,而无需通过将存储库与Finders分开来分开数据库的复杂性,请阅读此 post
6 2023-08-08
编程技术问答社区
使用Entity Framework 4.1和父/子关系的存储库模式
我仍然对存储库模式有一些混乱.我要使用这种模式的主要原因是避免从域调用EF 4.1特定数据访问操作.我宁愿从iRepository接口中调用通用的CRUD操作.这将使测试变得更容易,如果我将来必须更改数据访问框架,我将能够在不重构大量代码的情况下这样做. 这是我情况的一个例子: 我在数据库中有3个表:Group,Person和GroupPersonMap. GroupPersonMap是一个链接表,仅由Group和Person主键组成.我使用VS 2010 Designer创建了3个表的EF模型. EF足够聪明,可以假设GroupPersonMap是一个链接表,因此它不会在设计师中显示.我想使用现有的域对象,而不是EF的生成类,因此我关闭了该模型的代码生成. 我与EF模型匹配的现有类如下: public class Group { public int GroupId { get; set; } public string Name { get; se
什么是聚合根?
我试图围绕如何正确使用存储库模式.总体根源的核心概念不断出现.当搜索网络和堆栈溢出以寻求汇总根本是什么时,我一直在寻找有关它们的讨论以及与应该包含基本定义的页面的链接. 在存储库模式的上下文中,什么是骨料根? 解决方案 在存储库模式的上下文中,聚合根是您的客户端代码从存储库中加载的唯一对象. 存储库封装对子对象的访问 - 从呼叫者的角度来看,它会自动加载它们,同时加载根或实际需要时(如懒惰加载). 例如,您可能有一个Order对象,该对象将操作封装在多个LineItem对象上.您的客户端代码永远不会直接加载LineItem对象,只有包含它们的Order,这将是您域那部分的总词根. 其他解决方案 来自Evans DDD: 聚合是一个关联对象的群集,我们将其视为数据更改的目的.每个骨料都有根和边界.边界定义了骨料内部的内容.根是骨料中包含的单个特定实体. 和: root是允许外部对象保存[.] 的唯一汇总成员 这意味着聚集根是可以从存储
22 2023-08-08
编程技术问答社区
领域驱动的设计和汇总参考
我正在设计域模型,但是似乎还不错. 我从主聚合开始.它也引用了其他聚合物,而其他聚集体也引用了更多的聚集体.我可以从主骨头开始旅行孔域模型. 我看到的问题是我将在内存中持有所有聚合的实例. 那是一个好设计吗?我可以通过懒惰加载来解决内存问题,但我认为我有一个更深的问题. 我还有另一个有关汇总参考的问题.我应该加载对其他聚集体的参考吗?如果是这种情况,我几乎永远不会用他们的存储库用户.可以吗? 解决方案 在聚集根(ARS)之间直接引用可以导致无法通过懒负荷解决的问题.此外,它迫使所有连接的AR都处于相同的数据库中,并且使对不变的不变性更难进行推理和执行,这首先是AR的主要目的.最好限制或消除AR之间的直接参考.了解汇总设计的一个很好的资源是系列文章 vaughn vernon .基本思想是使您的ARS倾斜和集中精力,同时牢记其功能 - 执行业务限制并在根实体周围锻造边界.如果AR需要来自另一个AR的数据来执行其工作,则可以通过存储库通过应用程序服务向其提供此
16 2023-08-08
编程技术问答社区
如何避免总量依赖外部包括?
我不使用懒惰的加载.我的根部骨料具有实体(集合导航属性).我希望我的汇总是独立的,对自己负责,并遵循单一的责任原则(SRP),并遵守高凝聚力和低耦合. 问题是检索根骨料的代码需要包括某些子实体,具体取决于它想要与骨料进行交互的方式. 示例: public class Blog // My root aggregate { public ICollection Authors { get; set; } public ICollection Posts { get; set; } public AddAuthor(Author author) { _authors.Add(author); } public AddPost(Post post) { _posts.Add(post); } } 如果我想添加作者,我必须做: var blo
处理总根
我是DDD的新手,所以我正在做一些练习以进行更多的工作.我的课程BC具有以下规则: 必须首先创建课程,然后他们可以创建一个课程的模块 用户上传作业时,每个模块都会由用户完成 用户完成所有模块后,该课程将由用户完成 定义: 课程涵盖了一个特定的主题,它由模块组成.例如,SAP课程具有10个模块,例如:模块1:它是什么?,模块2:如何使用它?… 之后,我意识到该课程是模块的总体根源,因为模块完成了,我必须通过课程关闭用户的状态. 模型将是: public class Course : AggregateRoot { private string title; private List modules; } ,但也是模块是家庭作业的总体根源,因为当用户上传他的作业时,必须关闭模块.这使我认为这种方法是错误的,因为在DDD中不可能嵌套骨料.有人知道怎么了吗? [更新] 好吧,现在我明白了如何工作以及为什么在公元前2
20 2023-04-18
编程技术问答社区