.NET 中的 DDD / 聚合

2024-03-13

我一直在阅读 Evans 关于 DDD 的书,并且正在思考应该如何在 .NET 中实现聚合。目前,我只能想出一种方法;将聚合隔离在单独的类库中。然而,这似乎有点矫枉过正(我更愿意将所有域对象保留在一个库中),我想知道是否有不同的方法?

1 lib/aggregate 的推理如下:聚合根需要知道对其负责的“子对象”的所有访问,并且聚合根还可以返回子对象作为其成员的结果。因此,这些子对象的成员(聚合根所需的)不能公开。因此,您唯一的选择是将它们设置为内部(因为它们仍然需要由聚合根调用)。然而,通过将所有聚合放入一个项目中,仍然可以从已获取子对象的其他域对象访问这些成员。这是不可取的,因为它允许人们绕过聚合根。通过分离不同库中的所有聚合,这个问题就得到了解决。

一些附加信息:

我已经检查过DDD java 示例代码 http://dddsample.sourceforge.net/并且它们将每个聚合(包括所有子对象的类)打包在不同的包中。只能从聚合根调用的成员没有访问修饰符(例如:Delivery.updateOnRouting)。在java中,没有访问修饰符的成员是包私有 http://download.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html(仅可从同一包中获得)。所以这将是正确的行为。

The .NET 示例代码 http://dddsamplenet.codeplex.com/然而,将所有域对象放入一个类库中,然后将相应的成员设为公共。对我来说,这似乎是不正确的。


聚合是 DDD 中最难的概念之一。你大部分都是对的。我建议用聚合的“成员资格”来表达这个概念比引入术语“子对象”更直接。

是的,一个对象不能是多个聚合的成员。哪一个将是最终的执行者?一个聚合根可以通过删除成员并孤立另一个聚合中的其他成员来轻松使另一个聚合根失效。您是对的,在一个对象似乎需要多个聚合中的成员资格的情况下,该对象必须是一个独立的实体,即它成为新聚合的根。 (它可能有也可能没有其他成员,但如果没有,那么它当然会成为它自己的聚合体。)

是的,确实存在一个聚合来强制不变量。就持久性而言,它也是单个工作单元或单个事务。聚合根最终对其整个成员资格中的所有不变量负责,这一定是因为,例如,不变量的失败可能会导致持久性失败,而聚合负责将聚合维护为持久性工作的可行的单个单元。

然而,这是微妙和困难的部分,最终的责任并不意味着总体也是primary执行者也。就像我们的司法系统一样——法院最终是决定法律问题的最终场所,也是实施最终法治、执行不变量的地方。但实际执行(和合规)发生在系统的许多级别。事实上,在一个秩序良好的社会中,大多数实施法治的活动——执行不变量——应该在你到达法庭之前就发生,你甚至根本不必依赖例行公事。 (尽管在 DDD 中,您可能总是希望聚合根在持久化之前进行最终的不变扫描。)

你的建议就很不一样了,本质上你们整个社会除了法庭之外都被监禁了,而且你似乎还建议其他人甚至不能探视,只能向法庭传递信息,希望法庭能够采取适当的行动。

让我们看看如果您按照建议的路径操作,您的域会发生什么情况。目标是创建一个丰富且富有表现力的领域模型。就有意义的普遍语言而言,您已将工作词汇量减少到仅聚合词根。由于不变量,实体应该由聚合根访问,而且还因为如果设计正确,则实体具有有意义的标识,该标识源自其聚合根上下文中的成员身份。但是您的建议实体在其聚合根之外甚至没有任何类型标识。埃文斯特别指出,这是聚合根的目的的一部分——允许对象通过遍历来获取对成员的引用。但是您无法获得有用的引用,因为另一个对象甚至不知道您的成员类型存在。或者您可以更改名称空间,但如果您不允许遍历,那也好不到哪儿去。现在,您的整个域都知道类型,但永远无法获取对象的类型。

更糟糕的是你的聚合根会发生什么。除了维护聚合完整性之外,聚合根通常应该有其自身存在的理由。但现在这个身份已经不明确了。它因需要为所有各种元素及其属性提供包装方法而变得模糊。你得到的是聚合根,不再具有表现力,甚至没有明确的身份,只是巨大而笨拙的上帝物体。

您的 Order 和 OrderLine 示例就是一个有趣的例子。该订单不代表订单行强制执行订单行所需的某些不变量。在这种情况下,它控制动作以强制执行它自己的不变量。这是控制聚合根的有效操作。然而,更典型的聚合主要涉及对象的创建和/或销毁。

当然,不需要强加一个模型,其中所有状态更改都必须由聚合根自动应用,而不是直接应用。事实上,这通常就是聚合根允许遍历获取对成员的引用的原因 - 因此外部对象可以应用状态更改,但在聚合控制要更改的成员实体的实例生命周期的上下文中。

不仅可见性,而且与更大领域的实际交互通常也是开发丰富且富有表现力的模型的基础。聚合用于控制该访问,但不能完全消除它。

我希望这会有所帮助,这是一个很难讨论的概念。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.NET 中的 DDD / 聚合 的相关文章

  • INSERT..RETURNING 在 JOOQ 中不起作用

    我有一个 MariaDB 数据库 我正在尝试在表中插入一行users 它有一个生成的id我想在插入后得到它 我见过this http www jooq org doc 3 8 manual sql building sql statemen
  • Spark 1.3.1 上的 Apache Phoenix(4.3.1 和 4.4.0-HBase-0.98)ClassNotFoundException

    我正在尝试通过 Spark 连接到 Phoenix 并且在通过 JDBC 驱动程序打开连接时不断收到以下异常 为简洁起见 下面是完整的堆栈跟踪 Caused by java lang ClassNotFoundException org a
  • 什么时候值得使用 BindingSource?

    我想我非常了解 BindingSource 类的作用 即在数据源和 UI 控件之间提供一个间接层 它实现了 IBindingList 接口 因此还提供了对排序的支持 而且我已经经常使用它 没有太多问题 但我想知道我使用它的频率是否超过了应有
  • 反射找不到对象子类型

    我试图通过使用反射来获取包中的所有类 当我使用具体类的代码 本例中为 A 时 它可以工作并打印子类信息 B 扩展 A 因此它打印 B 信息 但是当我将它与对象类一起使用时 它不起作用 我该如何修复它 这段代码的工作原理 Reflection
  • 我可以使用 HSQLDB 进行 junit 测试克隆 mySQL 数据库吗

    我正在开发一个 spring webflow 项目 我想我可以使用 HSQLDB 而不是 mysql 进行 junit 测试吗 如何将我的 mysql 数据库克隆到 HSQLDB 如果您使用 spring 3 1 或更高版本 您可以使用 s
  • Mockito when().thenReturn 不必要地调用该方法

    我正在研究继承的代码 我编写了一个应该捕获 NullPointerException 的测试 因为它试图从 null 对象调用方法 Test expected NullPointerException class public void c
  • Spring @RequestMapping 带有可选参数

    我的控制器在请求映射中存在可选参数的问题 请查看下面的控制器 GetMapping produces MediaType APPLICATION JSON VALUE public ResponseEntity
  • 如何将 pfx 文件转换为 jks,然后通过使用 wsdl 生成的类来使用它来签署传出的肥皂请求

    我正在寻找一个代码示例 该示例演示如何使用 PFX 证书通过 SSL 访问安全 Web 服务 我有证书及其密码 我首先使用下面提到的命令创建一个 KeyStore 实例 keytool importkeystore destkeystore
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • 有没有办法将应用程序覆盖在全屏程序上?

    我希望开发一个应用程序 它本质上是一个计时器窗口 它始终显示在任何其他应用程序前面的屏幕上 并且在聚焦其他窗口时永远不会落入背景 一个例子是 当我玩全屏游戏时 我希望这个计时器覆盖游戏 并且当我单击窗口上的计时器按钮时 它不会关闭游戏 我有
  • 无法捆绑适用于 Mac 的 Java 应用程序 1.8

    我正在尝试将我的 Java 应用程序导出到 Mac 该应用程序基于编译器合规级别 1 7 我尝试了不同的方法来捆绑应用程序 1 日食 我可以用来在 Eclipse 上导出的最新 JVM 版本是 1 6 2 马文 看来Maven上也存在同样的
  • Java列表的线程安全

    我有一个列表 它将在线程安全上下文或非线程安全上下文中使用 究竟会是哪一个 无法提前确定 在这种特殊情况下 每当列表进入非线程安全上下文时 我都会使用它来包装它 Collections synchronizedList 但如果不进入非线程安
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • Firebase 添加新节点

    如何将这些节点放入用户节点中 并创建另一个节点来存储帖子 我的数据库参考 databaseReference child user getUid setValue userInformations 您需要使用以下代码 databaseRef
  • 使用 JMF 创建 RTP 流时出现问题

    我正处于一个项目的早期阶段 需要使用 RTP 广播DataStream创建自MediaLocation 我正在遵循一些示例代码 该代码目前在rptManager initalize localAddress 出现错误 无法打开本地数据端口
  • JGit 检查分支是否已签出

    我正在使用 JGit 开发一个项目 我设法删除了一个分支 但我还想检查该分支是否已签出 我发现了一个变量CheckoutCommand但它是私有的 private boolean isCheckoutIndex return startCo
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j

随机推荐

  • 在 Web.Config 中添加 HtmlHelper NameSpace 不起作用

    问题一 我已经开始学习ASP NET MVC 我做了一个简单的扩展方法 如下所示 namespace MvcTestz Project is also named as MvcTestz public static class Submit
  • 删除视频缩略图上的黑条

    我有一个画廊 用户可以在其中提交视频的 Youtube 链接 服务器会自动从 Youtube 获取缩略图 然而 许多视频的图像顶部和底部都包含黑条 我知道黑条的起源 但当我将缩略图大小调整为正方形时 黑条会干扰设计 我尝试从上到下分析像素颜
  • 缺少 mcrypt 扩展名。请检查您的 PHP 配置

    我刚刚按照位于的教程进行操作https www digitalocean com community articles how to install linux apache mysql php lamp stack on ubuntu h
  • 完全隐藏 Chart.js 中的空条

    In my Chart js 条形图 每个标签大约有 6 个数据集 其中一些数据集的值为 0 这会导致 x 轴上出现空白 请参阅 我想删除这些空白 我该怎么做 从数据库呈现我的代码后 它看起来像这样 请注意 为了简单起见 我大大减少了代码
  • 如何将系统分解为模块?

    模块化 的有效性取决于将系统划分为模块所使用的标准 我想要的是 提出一些可用于将系统分解为模块的标准 Cohesion http en wikipedia org wiki Cohesion computer science 模块中的功能是
  • 如何在 Dragover/dragenter HTML 5 拖放过程中更改图标

    如何在 Dragover 或 Dragenter 过程中更改 DnD 拖放 图标 有可能吗 如果拖放源位于 html 页面内部 例如将一个 div 拖到另一个 div 中 我可以在拖拽启动期间更改图标 这是我的代码 我正在使用角度 我已经设
  • 在 if 语句中展开多个选项

    我想在一个 if 语句中解开两个选项 但编译器抱怨密码常量运算符后的预期表达式 可能是什么原因 if let email self emailField text let password self passwordField text d
  • 如何强制 Google Charts vAxes 渲染?

    目前 我在页面上渲染两个图表 我正在使用谷歌的可视化图表库 由于页面大小问题 vAxes 在某些 大部分时间拒绝渲染 如果我给它足够的空间 它就会很好地渲染轴 但如果它稍微偏离 即使有足够的空间容纳这些该死的轴 它们也会拒绝渲染 我不能这样
  • Windows Phone IE 移动 bug 具有透明背景图像和底部绝对定位

    我在使用 WP IE 时遇到两个问题 透明背景图像的透明边框上有伪影 绝对定位的 div 到页面底部在浏览器导航栏和页面底部之间留下约 5px 的白色间隙 请注意 我使用 div 而不是 img 来处理CSS 视网膜图像替换 http co
  • 透明状态栏不适用于 windowTranslucentNavigation="false"

    我正在开发一个Activity我需要在运行 5 0 API 21 的设备上使导航栏不透明 并使状态栏透明 下面是我使用的样式 以及对我的问题的解释 AppTheme延伸Theme AppCompat Light NoActionBar
  • 从非托管 C 调用托管代码

    因此 经过大约一天半的时间 我的进展为零 我需要用 C 语言编写一个 DLL 用作现有应用程序的插件 DLL 必须由 Visual Studio 2008 编译器使用以下选项进行编译 cl DNT40 DPOMDLL DCRTAPI1 cd
  • MySQL 多 ID 查找

    我正在尝试向系统添加全文搜索 我想要编写的查询需要涉及多次查找 然后进行搜索 如果可能的话 我有一张教师表和一张科目表 teacherProfile teacherId int primary key subjectOneId int su
  • 读取时出现 Ruby CSV UTF8 编码错误

    这就是我正在做的 csv CSV open file name r 我用它来测试 line csv shift while not line nil puts line line csv shift end 我遇到了这个 ArgumentE
  • html中有vr(垂直规则)吗?

    我知道html中有hr 水平规则 但我不相信有vr 垂直规则 我错了吗 如果没有 为什么没有垂直规则 不 没有垂直规则 编辑 现在是 2021 年 我回答这个问题十二年后 我不再认为我原来的解释是正确的 原文解释 拥有一个没有逻辑意义 HT
  • 具有相同名称/路径的多个 cookie 的浏览器行为

    我对当存在多个具有相同名称和路径且对当前域有效的 cookie 时各种浏览器的行为感兴趣 例如 浏览器存储了这两个cookie key value path domain foo bar baz key value path domain
  • 为什么 svn import 选项无法检测文件重复

    如果我想签入 SVN 中已存在的同名文件 在这种情况下我将无法提交 例如 Name doc and name doc 但是 在这种情况下我将能够导入 这种情况甚至适用于文件夹名称 这可以防止将来进行结账操作 有没有办法防止文件或文件夹重复
  • 运行桌面版 libgdx 示例 gdx-invaders 时出现 java.lang.NoClassDefFoundError

    我正在构建 libgdx 的 gdx invaders 示例 有两个项目 gdx入侵者 基础项目 作为桌面 Java 应用程序运行gdx 入侵者 android项目 依赖于 gdx invaders 并作为 Android 应用程序运行 我
  • Golang反射:无法设置包装结构的接口字段

    我正在尝试实现一种方法 该方法可以更改可以具有任意结构的对象中的字段值 当我有指向结构的指针时 字段的遍历没有问题 但是 当我有一个接口不包装指向结构的指针而是包装结构本身时 我无法设法更改字段 简而言之 The following doe
  • 我什么时候必须声明 session_start(); ?

    所以我是 PHP 的初学者 所以我需要一些帮助 我正在尝试确定何时开始会议 我应该在用户首次注册时执行此操作还是在用户登录时执行此操作 另外 会话是否 通用 意味着当我检查会话时它会起作用还是我必须在所有页面中包含一个文件来检查某人是否有会
  • .NET 中的 DDD / 聚合

    我一直在阅读 Evans 关于 DDD 的书 并且正在思考应该如何在 NET 中实现聚合 目前 我只能想出一种方法 将聚合隔离在单独的类库中 然而 这似乎有点矫枉过正 我更愿意将所有域对象保留在一个库中 我想知道是否有不同的方法 1 lib