ORM中的Model与DDD中的DomainModel

0.引言

在现有的系统开发中,大部分的系统应该都会用到ORM,无论用的是EF还是NHibernate。作为对象和持久化数据的桥梁,ORM确实非常方便,以至于在DDD的时候,我们很自然的将 ORM中的Model(实体)表达成DDD中的 DomainModel(领域对象)。

但这真的合理吗?我们先引入两个例子来探讨这个问题。

1.例子1:订单聚合

下述聚合引自汤神的博客:

我们看以上的聚合设计非常经典。Order对象作为聚合根,OrderItem建模成实体,只要在当前的订单聚合中不重复即可。

但在真正的数据存储的时候,我们的OrderItem对象肯定不能是这样子的。

假如:我们有两个订单A和B,订单A包含了商品1和商品2,订单2包含商品2和商品3。

那么很明显我们如果以OrderItem这个实体去存储,必然会造成主键重复。在实际存储的时候我们肯定也会为OrderItem增加其他的字段用来存储他自己的主键信息。

比如我们给他建立一个独立的ID:

 public class OrderItem{/// <summary>/// 订单项ID/// </summary>public string Id { get; set; }public string ProductId { get; set; }public string ProductName { get; set; }public float Price { get; set; }public int Count { get; set; }}

或则采用联合主键:

    public class OrderItem{/// <summary>/// 订单ID/// </summary>public string OrderId { get; set; }public string ProductId { get; set; }public string ProductName { get; set; }public float Price { get; set; }public int Count { get; set; }}

2.例子2:旅馆聚合与房间聚合

在旅馆信息系统管理里面,对旅馆的操作会有独立的模块,参考聚合的设计原则

  1. 如果领域内的一个对象,我们会在后台有一个独立的模块去管理它,那它基本上也是聚合根了;

所以我们建立旅馆聚合,代码如下:

    public class Hotel{/// <summary>/// 聚合跟id/// </summary>public string Id { get; set; }/// <summary>/// 值对象/// </summary>public string Name { get; set; }/// <summary>/// 房间列表 此处简单标示        /// </summary>public IList<string> Rooms { get; set; }//其他信息略//...}

对于旅馆房间的也一样我们会有单独的模块去管理,而且房间有单独的状态标示(房间是否有人入住,是否空房等等)

房间聚合如下:

  public class Room{/// <summary>/// 房间id/// </summary>public string Id { get; set; }public string Name { get; set; }public string RoomType { get; set; }// 空 已预订,已入住,脏房间等状态public RoomStatus Status { get; set; }/// <summary>/// 旅馆聚合根ID/// </summary>public string HotelId { get; set; }}

如果是在ORM中上述很可能表达成如下实体:

    public class Hotel{public string Id { get; set; }public string Name { get; set; }/// <summary>/// 房间列表    /// </summary>public virtual IList<Room> Rooms { get; set; }//其他信息略//...}

和房间实体

 public class Room{/// <summary>/// 房间id/// </summary>public string Id { get; set; }public string Name { get; set; }public string RoomType { get; set; }// 空 已预订,已入住,脏房间等状态public RoomStatus Status { get; set; }/// <summary>/// 旅馆/// </summary>public virtual Hotel Hotel { get; set; }}

很明显的可以看出,上述模型不是DDD中的领域对象模型。

3.结论:ORM中的Model不应该与DDD中的DomainModel等价

更多的:我们在设计数据库表的时候,为了查询性能考虑,会冗余一些信息等等。

通过以上的分析,我们可以得出结论:ORM中的Model不应该与DDD中的DomainModel等价。

我藉著本文来抛砖引玉。

国外的大牛写的:Just-Stop-It!-The-Domain-Model-Is-Not-The-Persistence-Model.aspx

转载于:https://www.cnblogs.com/zhengqzheng/p/5883612.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457261.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基础总结

Unsafe Java线程池 HashCode 垃圾收集 关于引用&#xff08;弱引用、强引用等等&#xff09;转载于:https://www.cnblogs.com/aquariusm/p/6340303.html

jsp java语法_JSP基础语法

Java JSP 的 JSP基础语法在本章中&#xff0c;我们将了解和学习JSP语法。并了解JSP开发涉及的简单语法(即元素)的基本用法。为了方便演示&#xff0c;使用Eclipse创建一个动态Web项目&#xff1a;jspsyntax&#xff0c;用于运行以下涉及到的示例代码。JSP的元素JSP的元素如下所…

iOS - Core Animation 核心动画

1、UIView 动画 具体讲解见 iOS - UIView 动画2、UIImageView 动画 具体讲解见 iOS - UIImageView 动画3、CADisplayLink 定时器 具体讲解见 iOS - OC NSTimer 定时器CADisplayLink 是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器。我们在应用中创建一个新的…

navicat 官方使用手册,中文版,快捷键大全

2017年1月23日09:52:51 这个官方中文文档很详细 https://www.navicat.com.cn/manual/online_manual/cn/navicat/win_manual/index.html https://community.navicat.com/videos/cn 官方中文论坛部分视频教程 快捷键 Navicat 主窗口 键动作CTRLG设置位置文件夹CTRL#&#xff08;#…

Linux inode与文件系统关系

inode只有在linux文件系统的概念&#xff08;ext3,ext4) 、inode节点数量与文件存储的关系。 二、在文件系统初始化时设置合适的节点数量。 linux服务器在存储文件小而数量多的情况下&#xff0c;需要考虑inode用完的情况。转载于:https://www.cnblogs.com/lirunzhou/p/5883706…

评分系统 java_C自动评分系统

我无法按照规范完成作业 . 这是分配方案&#xff1a;大学迫切需要一个自动测试评分系统 . 使用C&#xff0c;为大学写一个评分系统&#xff0c;并对至少五名学生的测试进行评分 . 要创建评分系统&#xff0c;请按照以下步骤操作&#xff1a;首先询问测试中的问题数量然后询问每…

当Terraform遇上ECS(一)——DataSource篇

背景 越来越多的公司已经熟知并运用“基础设施即代码”来构建和维护自己的云基础设施。目前也有许多的自动化构建工具协助用户通过脚本进行云资源的部署和生命周期的管理&#xff0c;如&#xff1a;Terraform、Ansible、Chef等。但是&#xff0c;在实施过程中&#xff0c;都遇到…

【BZOJ 1597】 [Usaco2008 Mar]土地购买 (斜率优化)

1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3601 Solved: 1322Description 农夫John准备扩大他的农场,他正在考虑N (1 < N < 50,000) 块长方形的土地. 每块土地的长宽满足(1 < 宽 < 1,000,000; 1 < 长 < 1,000,000). …

深入浅出学java_《深入浅出学JAVA开发初级》

整体说明&#xff1a;Java私塾的这一套视频是完全真实课堂录制&#xff0c;实际上课时间为十一天&#xff0c;主要内容包括&#xff1a;1&#xff1a;系统完整的学习Java的基础知识2&#xff1a;深入剖析重点知识点的理论3&#xff1a;超多的编程题目和程序讲解4&#xff1a;最…

重定位与链接脚本

1.为什么需要重定位   位置无关编码(PIC&#xff0c;position independent code)&#xff1a;汇编源文件被编码成二进制可执行程序时编码方式与位置&#xff08;内存地址&#xff09;无关。  位置有关编码&#xff1a;汇编源码编码成二进制可执行程序后和内存地址是有关的。…

Linux bashrc和profile的用途和区别

导读使用终端ssh登录Linux操作系统的控制台后&#xff0c;会出现一个提示符号&#xff08;例如&#xff1a;#或~&#xff09;&#xff0c;在这个提示符号之后可以输入命令&#xff0c;Linux根据输入的命令会做回应&#xff0c;这一连串的动作是由一个所谓的Shell来做处理。Shel…

python读取word文档结构图_Word 有什么技巧,让你相见恨晚?

Word作为日常办公最常用的软件之一&#xff0c;其实真没你想得那么简单&#xff01;你不知道的每一个技巧&#xff0c;都会让你相见恨晚&#xff01;每当身边的小伙伴询问这些疑难杂症时&#xff0c;我都会抛出这张图…真的没骗你&#xff0c;我们遇到的 99% 的Word难题&#x…

Golang 特性简介

by sheepbao 主要大概介绍go语言的历史和特性&#xff0c;简单的入门。 来历 很久以前&#xff0c;有一个IT公司&#xff0c;这公司有个传统&#xff0c;允许员工拥有20%自由时间来开发实验性项目。在2007的某一天&#xff0c;公司的几个大牛&#xff0c;正在用c开发一些比较繁…

HTML实体字符转化为HTML标签

html_entity_decode方法 参数描述string必需。规定要解码的字符串。flags 可选。规定如何处理引号以及使用哪种文档类型。 可用的引号类型&#xff1a; ENT_COMPAT - 默认。仅解码双引号。ENT_QUOTES - 解码双引号和单引号。ENT_NOQUOTES - 不解码任何引号。规定所使用文档类型…

华为2017java笔试题_2017年java华为面试题

2017年java华为面试题通过HCNP认证&#xff0c;将证明您对中小型网络有全面深入的了解&#xff0c;掌握中小型网络的通用技术&#xff0c;并具备独立设计中小型网络以及使用华为路由交换设备实施设计的能力。下面是小编收集的关于java华为面试题&#xff0c;希望大家认真阅读!1…

Tomcat 配置详解/优化方案

Server.xml 【原地址&#xff1a;http://blog.csdn.net/cicada688/article/details/14451541】 Server.xml配置文件用于对整个容器进行相关的配置。 <Server>元素&#xff1a;是整个配置文件的根元素。表示整个Catalina容器。 属性&#xff1a;className&#xff1a;实现…

MySQL创建数据库与创建用户以及授权

1、create schema [数据库名称] default character set utf8 collate utf8_general_ci;--创建数据库 采用create schema和create database创建数据库的效果一样。 2、create user [用户名称]% identified by [用户密码];--创建用户 密码8位以上&#xff0c;包括&#xff1a;大写…

java 防止url重复请求_Web项目如何防止客户端重复发送请求

在Web项目中&#xff0c;有一些请求或操作会对数据产生影响(比如新增、删除、更新)&#xff0c;针对这类请求一般都需要做一些保护&#xff0c;以防止用户有意或无意的重复发起这样的请求导致的数据错乱。本文总结了一些防止客户端重复发送请求的方法。方法一&#xff1a;JS监听…

【bzoj1010-toy】斜率优化入门模板

dsy1010: [HNOI2008]玩具装箱 【题目描述】 有n个数&#xff0c;分成连续的若干段&#xff0c;每段&#xff08;假设从第j个到第i个组成一段&#xff09;的分数为 (X-L)^2&#xff0c;X为j-iSigma(Ck) i<k<j&#xff0c;其中L是一个常量。目标&#xff1a;各段分数的总和…