.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 / 聚合 的相关文章

  • Powershell XMLDocument保存为无BOM的UTF-8

    我构建了一个 System Xml XmlDocument 类型的 XML 对象 scheme gettype IsPublic IsSerial Name BaseType True False XmlDocument System Xm
  • 如何在 WPF 应用程序中实现气球消息

    我们想使用气球消息 如UX Guide http msdn microsoft com en us library aa511451 aspx来自微软 我发现一些示例使用 Windows 窗体中的本机代码 但本机代码需要组件的句柄 这对于
  • 标签中的路径显示

    NET 中有没有自动修剪路径字符串的方法 例如 C Documents and Settings nick My Documents Tests demo data demo data emx becomes C Documents dem
  • 2^31 次方的 Java 指数错误 [重复]

    这个问题在这里已经有答案了 我正在编写一个java程序来输出2的指数幂 顺便说一句 我不能使用Math pow 但是在 2 31 和 2 32 处我得到了其他东西 另外 我不打算接受负整数 My code class PrintPowers
  • 是否有用户友好的 Log4Net 日志文件查看器? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 是否有任何第三方工具可以识别 Log4Net 日志文件结构并通过提供搜索功能等以用户友好的方式显示它 Try 色域日志查看器 https source
  • 为什么解析这个 JSON 会抛出错误?

    我正在尝试解析这个 JSONObject query yahoo count 1 results rate Name USD INR id USDINR Time 12 19pm Date 10 31 2015 Bid 65 405 Ask
  • Android 认为我没有关闭数据库!为什么?

    我有一个 SQLiteDatabase 数据成员 我在 onCreate 中初始化它 并在 onPause onStop 和 onDestroy 中调用 close 它在 onResume 中重新初始化 它似乎运行得很好 但当我查看调试器时
  • WPF 中的屏幕分辨率问题?

    我将在 WPF 中使用以下代码检测分辨率 double height System Windows SystemParameters PrimaryScreenHeight double width System Windows Syste
  • 类更改(例如字段添加或删除)是否保持 Serialized 的向后兼容性?

    我有一个关于 Java 序列化的问题 在这种情况下 您可能需要修改可序列化类并保持向后兼容性 我有丰富的 C 经验 所以请允许我将 Java 与 NET 进行比较 在我的Java场景中 我需要使用Java的运行时序列化机制序列化一个对象 并
  • Joshua Bloch 的构建器设计模式有何改进?

    早在 2007 年 我就读过一篇关于 Joshua Blochs 所采用的 构建器模式 的文章 以及如何修改它以改善构造函数和 setter 的过度使用 特别是当对象具有大量属性 其中大部分属性是可选的 时 本文对此设计模式进行了简要总结
  • Java 8 Stream,获取头部和尾部

    Java 8 引入了Stream http download java net jdk8 docs api java util stream Stream html类似于 Scala 的类Stream http www scala lang
  • ASP.NET Core 与现有的 IoC 容器和环境?

    我想运行ASP NET 核心网络堆栈以及MVC在已托管现有应用程序的 Windows 服务环境中 以便为其提供前端 该应用程序使用 Autofac 来处理 DI 问题 这很好 因为它已经有一个扩展Microsoft Extensions D
  • 文本视图不显示全文

    我正在使用 TableLayout 和 TableRow 创建一个简单的布局 其中包含两个 TextView 这是代码的一部分
  • 使用 WF 的多线程应用程序的错误处理模式?

    我正在写一个又长又详细的问题 但只是放弃了它 转而选择一个更简单的问题 但我在这里找不到答案 应用程序简要说明 我有一个 WPF 应用程序 它生成多个线程 每个线程执行自己的 WF 处理线程和 WF 中的错误 允许用户从 GUI 端进行交互
  • Spring Data Rest 多对多 POST

    首先 让我解释一下我的用例 这非常简单 有一个用户实体和一个服务实体 我使用 UserService 作为连接实体 连接表 在用户和服务之间建立多对多关联最初 会有一些用户集和一些服务集 用户可以在任何时间点订阅任何服务 在这种情况下 将向
  • 使用 Apache 允许 Glassfish 和 PHP 在同一服务器中协同工作

    是否可以建立从 Java 到 php 文件的桥梁 我有一个用 Java 编写的应用程序 我需要执行http piwik org http piwik org 这是用 PHP 编写的 在服务器中 我正在运行 PHP 但无法从浏览器访问 php
  • 检测到 JVM 正在关闭

    我有一个使用 addShutdownHook 处理 Ctrl C 的 Swing 应用程序 它工作正常 直到我的关闭任务之一调用一个在正常情况下更改 JLabel 文本的函数 此时它挂起 我认为问题是 Swing EDT 已终止或正在等待某
  • 使用 DBCP 配置 Tomcat

    在闲置一段时间 几个小时 后 我们收到了 CommunicationsException 来自 DBCP 错误消息 在异常中 位于这个问题的末尾 但我没有看到任何配置文件中定义的 wait timeout 我们应该看哪里 在 tomcat
  • 为什么文件更新时“如果较新则复制”不复制文件?

    我在 Visual Studio Express 中有一个解决方案 如下所示 The LogicSchemaC 中的类 将在运行时解析指定的 XML 文件 以下是在main的方法Program cs LogicSchema ls new L
  • Spring 作为 JNDI 提供者?

    我想使用 Spring 作为 JNDI 提供程序 这意味着我想在 Spring 上下文中配置一个 bean 可以通过 JNDI 访问该 bean 这看起来像这样

随机推荐

  • 在 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