首页 新闻 会员 周边

直接采用DDD指导思想下领域层的Domain Model作为Entity Framework的Model是否是最佳实践?

0
悬赏园豆:10 [已解决问题] 解决于 2017-03-31 13:21

以DDD下的理念,Domain Model设计的过程中是不应该关心数据库的,但是网上的大部分博客资料及相关的专业书籍都并没有很清楚得解释到Domain Model 和 EF Model的关系,并且由于在EF框架的应用模式下,大部分的指导资料都直接使用Domain Model作为EF的Model使用,但这样不是违反了数据库无关性么?我个人的理解:对于大型应用程序来说,Domain Model并没有办法完全和面向数据库架构的Entity Model 完全做到一致,因为面向的方向不同,Domain Model 更多的是面向业务领域,而数据库的模型领域应该更多得考虑存储成本、检索效率、数据库大小等一切和运营成本有关系的东西,并不能和面向实际业务模型完全一致,大神们都是怎么看的?

夕阳寸草畔的主页 夕阳寸草畔 | 初学一级 | 园豆:48
提问于:2017-03-30 15:29
< >
分享
最佳答案
1

我觉得这个主要是看具体业务了,ddd思想并不是排除数据库的,ddd是解决业务上的问题,而存储的问题这块主要是靠仓储去进行包装。而一般业务场景下,领域模型就算和实际数据存储有代沟都通过各种方法去弥补了,比如最常见的orm,所以会出现ef上的model就可以从头走到尾。但这个不代表business object=data object。

正如你所说的很多时候我们不光要考虑业务上的实现,同时也要权衡存储或者性能上的要求,这些时候单纯的一个对象从头走到尾就不太合适了,orm也可能不能满足实际需求。既然矛盾太突出只能做取舍了,要么就是自己在中间加一层去适配这种差异,正真区分出来BO和DO(POCO/POJO);要么发现前面的做法太蛋疼或者有某些致命缺陷(比如按照ddd做某些大批量操作的性能或一致性上很可能有问题的),那么就让ddd滚蛋吧,毕竟ddd不是银弹,土枪土炮上阵不一定比意大利炮差。

回过头来说,ddd只能做辅助,虽然它描述的相当诱人,让你可以通过同一种语言来表达业务及技术实现,但这些东西要是真的用在一些特殊场景下(有技术性的特殊要求)我是觉得很难hold住,现实往往太过于残酷,看看隔壁的tdd,现在不还跪那被批在么。

收获园豆:10
Daniel Cai | 专家六级 |园豆:10424 | 2017-03-30 16:10

实际项目中取舍是肯定有的,但是按照目前广为流传的教程和指导原则,采用官方的EF框架应用Code First模式下,如果要合理配置数据库表和Model的对应关系,所需要涉及到的额外编码会远远超过分析Domain Model的复杂性,如果按照Code First的Model直接生成表是非常清楚明了的,但是就回到了上面的问题了。

夕阳寸草畔 | 园豆:48 (初学一级) | 2017-03-30 16:29

@夕阳寸草畔: 那只能说你的业务难度或技术要求没达到那个程度,我给你一个场景你可以看看

一个项目,发现必须要对数据做分片,然后发现分片后有些操作很难完成(数据被打散到不同片),因此只能做数据上的冗余,本来一个简单的用户或啥的信息需要额外记很多以前通过简单的join就可以完成的任务。

你看下在这种场景下一个ef model扛的住么?

Daniel Cai | 园豆:10424 (专家六级) | 2017-03-30 17:41

@Daniel Cai: 扛不住。但有没有比较流行做法或者框架能比较妥善地处理Domain Model 和 Entity Model 之间转换的关系,类似AutoMapping之类的东西?EF的官方指导是采用Domain Model在 DBContext 里进行手工编码自定义数据库表结构,这种做法能完美解决这个问题,但是就是编码有点蛋疼,并没有使用Entity Model 加上数据注解来得可读性强。

夕阳寸草畔 | 园豆:48 (初学一级) | 2017-03-31 10:56

@夕阳寸草畔:那么在这种情况下你就应该把ddd中的另一个东西给搬出来了--值对象。

Daniel Cai | 园豆:10424 (专家六级) | 2017-03-31 11:22

@Daniel Cai: 恕我愚钝,不太明白和“值对象”有什么关系。我目前的理解是,只要是需要持久化的对象,在ORM下应该有一层类,用于合理生成数据库,比如EF可以直接写Class,NHibernate可以写XML,现在我的场景是适用EF的Code First模式下,如果在DBContext下直接写DataMapper(网上大部分指导代码都如此),在Domain Model和表结构转换关系比较复杂时,这条路是非常不科学的,而如果像View Model 一样,直接写Entity Model生成了数据库表,然后在Repository里进行Domain Model 和 Entity Model 的Mapper,有没有成熟的解决方案?

夕阳寸草畔 | 园豆:48 (初学一级) | 2017-03-31 11:46

@夕阳寸草畔: ddd中的值对象是不可变的,在你划分领域模型的时候如果出现一些场景(比如我前面那个例子中有冗余信息),这些冗余信息就可以归纳为值对象。它同领域对象不同,但同时都属于ef的model吧?我说的这些只是为了反驳你问题中的model对model的问题。

然后回来再说你另外纠结的对象在不同层级映射的问题,我觉得这个已经超过了ddd的范畴。如果你同意我前一段的表述(model对model是不成立的),那么这个问题实际上就变成如何让ef实现1:N,这个在ef里应该是好实现的,你code first加几个attribute就能映射到不同的表上去吧。

还有一点你可以考虑下,当然我是不会这么玩的,只是刚才想到了:ddd思想你也可以贯穿到仓储的实现上。

别老纠结一个ef,ddd可比ef要早的多,如果没有ef的话难道ddd就不做了?

Daniel Cai | 园豆:10424 (专家六级) | 2017-03-31 12:20

@Daniel Cai: 好吧,我觉得已经偏题了。

夕阳寸草畔 | 园豆:48 (初学一级) | 2017-03-31 13:20
其他回答(2)
0

EF Model就当做Domain Model, Model 先按照业务进行划分处理,之后再通过技术映射到表,可能一张表 对应多个model,Model更多考虑业务,表 考虑持久化保存,再 通过mapping 联系起来,Model 和 表 不一定是一一对应关系

Qlin | 园豆:2403 (老鸟四级) | 2017-03-30 15:58

EF的指导实践采用Code First模式,在Code First模式下如果Model 和 表 要求能灵活对应,这个配置项可就复杂了,而且并不直观,我个人觉得这个不是最佳实践,肯定有更好的解决方案能处理Model和表的对应关系;

您这里提到的Mapping是正确的,但我的疑惑点在于这个Mapping的方式,如果把Domain Model 和 Entity Model 分成2个类,中间做Mapping,这种方式会额外增加一层,加上Domain Model 和 UI 层的View Model 也要有Mapping,还要算上DTO等类,在一个系统模型下,感觉这个类有点多了,Mapping 无数。

如果把Domain Model和Entity Model合并看待,采用Code First模式,在DBContext里进行Mapping的话,EF的这个设计语言真的有点蛋疼,如果类很多,估计这个Mapping都可以独立成新项目了。

支持(0) 反对(0) 夕阳寸草畔 | 园豆:48 (初学一级) | 2017-03-30 16:25
0

看看这个项目吧

http://git.oschina.net/lishilei0523/ShSoft.UAC

黄昏MMM | 园豆:320 (菜鸟二级) | 2017-03-30 16:14
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册