具有行为和 ORM 的丰富域模型

2024-03-26

观看 Jimmy Bogard 的 NDC12 演示“Crafting Wicked Domain Models”后(http://ndcoslo.oktaset.com/Agenda http://ndcoslo.oktaset.com/Agenda),我在想如何持久化这种领域模型。
这是演示中的示例类:

public class Member
{
    List<Offer> _offers;

    public Member(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
        _offers = new List<Offer>();
    }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public IEnumerable<Offer> AssignedOffers { 
        get { return _offers; }
    }

    public int NumberOfOffers { get; private set; }

    public Offer AssignOffer(OfferType offerType, IOfferValueCalc valueCalc)
    {
        var value = valueCalc.CalculateValue(this, offerType);
        var expiration = offerType.CalculateExpiration();
        var offer = new Offer(this, offerType, expiration, value);
        _offers.Add(offer);
        NumberOfOffers++;
        return offer;
    }
}

所以这个领域模型中包含一些规则:
- 会员必须有名字和姓氏
- 优惠数量无法在外部更改
- 会员负责创建新报价、计算其价值和分配

如果尝试将其映射到某些 ORM(例如 Entity Framework 或 NHibernate),它将无法工作。 那么,使用 ORM 将此类模型映射到数据库的最佳方法是什么?
例如,如果没有setter,如何从数据库加载AssignedOffers?

对我来说唯一有意义的是使用命令/查询架构:查询始终使用 DTO 作为结果,而不是域实体,并且命令是在域模型上完成的。此外,事件溯源非常适合领域模型上的行为。但这种 CQS 架构可能并不适合每个项目,特别是棕地项目。或不?

我知道这里有类似的问题,但找不到具体的例子和解决方案。


这其实是一个非常好的问题,也是我一直在思考的问题。创建完全封装的正确域对象(即没有属性设置器)并使用 ORM 直接构建域对象可能很困难。

根据我的经验,有3种方法可以解决这个问题:

  • 正如 Luka 已经提到的,NHibernate 支持映射到私有字段,而不是属性设置器。
  • 如果使用 EF(我认为不支持上述内容),您可以使用纪念品图案 http://en.wikipedia.org/wiki/Memento_pattern恢复域对象的状态。例如您使用实体框架来填充域实体接受的“备忘录”对象以设置其私有字段。
  • 正如您所指出的,将 CQRS 与事件源结合使用可以消除此问题。这是我制作完美封装的域对象的首选方法,它还具有事件溯源的所有附加优点。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有行为和 ORM 的丰富域模型 的相关文章

随机推荐

  • json_encode PHP 数组为 JSON 数组而不是 JSON 对象

    我在 PHP 中有以下数组 Array 0 gt Array id gt 0 name gt name1 short name gt n1 2 gt Array id gt 2 name gt name2 short name gt n2
  • 如何在给定宽度和高度的情况下调整对象的 2D 向量的大小?

    我的课 GameBoard 有一个成员变量 它是该类对象的二维向量Tile The GameBoard构造函数将宽度和高度作为参数 我怎样才能得到二维向量Tile根据传递给构造函数的宽度和高度调整对象大小 我怎样才能填充它Tile对象以便我
  • CSV 字符串到数据表

    我有以下字符串 我想将其转换为数据表 Id Name Dept r n1 Mike IT r n2 Joe HR r n3 Peter IT r n 我可以使用 String Split 并迭代集合来创建它 但我需要有效的方法 使用 C 4
  • 带有嵌入式哈希表的 Powershell ConvertTo-json

    我在 ConvertTo Json 方面遇到问题 并试图理解其行为和 或我做错了什么 考虑以下命令序列 val ID 10 Config ID 11 Config ID 12 Config end ConvertTo json val Co
  • dask 数据帧 head() 返回空 df

    我有一个 dask 数据框 其中一列上有索引 问题是如果我执行 df head 它总是返回一个空的 df 而 df tail 总是返回正确的 df 我检查过 df head 总是检查第一个分区中的前 n 个条目 因此 如果我执行 df re
  • 在 AppDomain 之间共享数据

    我有一个可以有多个应用程序域的进程 每个AppDomain 都会收集一些统计数据 在指定的时间之后 我想累积这些统计数据并将它们保存到文件中 实现此目的的一种方法是远程处理 我想避免这种情况 我想到的唯一其他技术是将每个应用程序域的数据保存
  • MVC contrib 寻呼机

    我这样使用它 有没有简单的方法来更改呈现的网址 我查找了更多文档 但找不到太多 你到底想改变什么 这是我更改 URL 的方法 Html Pager Model AssetsPagedList First First Last Last Ne
  • 如何在 Spark Dataframe 中按组/分区重命名列?

    我有一些传感器数据按通道名称而不是传感器名称存储在表中 这是为了避免表太宽 因为许多传感器仅在少数设备上使用 这是稀疏列的工作 我知道 但我只是数据的用户 像这样的事情 from functools import reduce import
  • 内存映射显示的 RAM 多于物理可用内存

    我正在开发一个小型 x86 内核 我正在访问并尝试读取 GRUB 在多重引导标头中提供的内存映射 我有一个 Intel i3 cpu 和 4 GiB RAM 在这台机器上运行时 我正在读取以下内存映射 Base Address Length
  • phpmyadmin的PHP不执行但其他php脚本可以运行

    调用 phpmyadmin 网站时 会出现 保存文件 对话框application x httpd php 所以我的服务器不执行 phpmyadmin php 脚本 而是将代码传输到我的浏览器 其他 php 如 roundcube 或 is
  • Gradle:下载包含的 aar-library 的依赖项

    我写了一个图书馆项目cameraBarcodeScanner它内置于 aar 文件中 该库在其 build gradle 中定义了以下依赖项 dependencies compile fileTree dir libs include ja
  • 根实体中的 GAE 事务

    我是 GAE 新手 对数据存储事务有一些疑问 例如 我有一个用户实体 当用户在 Facebook 上添加我的应用程序时创建该实体 我通过 Facebook API 获得了一些属性 但我想为用户添加用户名 并且该用户名必须是唯一的 所以在事务
  • 如何获取prometheus中(当前)建立的TCP连接数(kubernetes监控)

    我在 Linux 中使用此命令来查看 当前 建立的 TCP 连接 netstat ant grep ESTABLISHED wc l 我如何将此命令转换为 PromQL 每个节点 我在 kubernetes 集群中使用带有节点导出器的 pr
  • 如何使用 R 个性化时间线?

    我想用 R 绘制一个时间线 其中的时间段很容易识别 我可以在其中个性化可视化 periods 周期 盒子 的颜色 线条 颜色 位置 文本的位置并将其放入 框 中 轴 大小 颜色 选择重点 与事件相关的日期 etc 我使用时间线库 但是我找不
  • 如何触发Uploadify onError 事件处理程序?

    我在用上传 http www uploadify com 上传文件 问题是 我需要通知用户处理这些文件期间出现的任何错误 上传有onError onComplete and onAllComplete事件处理程序 但我不知道如何触发这些事件
  • Owin WS-Federation 设置令牌滑动过期

    有人可以解释如何使用新的实现滑动过期吗欧文WS 联合会 plugin 在客户端 在 WS Federation配置我看到有一些events like Notifications new WsFederationAuthenticationN
  • 在触摸屏上禁用文本输入上的 Chrome 粘贴菜单

    如何在触摸屏上禁用 Chrome 中这个烦人的上下文菜单 当我复制了一些文本时 在选择 长按任何输入时会弹出此窗口 我正在使用 CEFSharp Chromium 嵌入式框架 开发一个应用程序 并将其部署在 Windows 8 计算机的触摸
  • C# 中枚举对象的属性(字符串)

    假设我有很多对象 并且它们有很多字符串属性 是否有一种编程方式来遍历它们并输出属性名称及其值 或者是否必须进行硬编码 是否有一种 LINQ 方法来查询 字符串 类型的对象属性并输出它们 您是否必须对要回显的属性名称进行硬编码 使用反射 它远
  • 在 R 程序中排序后对行重新编号

    我已经订购了一组行来得到这个 2 1983 TRI COUNTY TRAUTH 0 1495 0 1395 NA 452 0 0764 4 0 06 02 83 4 1983 TRI COUNTY TRAUTH 0 1193 0 1113
  • 具有行为和 ORM 的丰富域模型

    观看 Jimmy Bogard 的 NDC12 演示 Crafting Wicked Domain Models 后 http ndcoslo oktaset com Agenda http ndcoslo oktaset com Agen