最新评论
Re:聚合(根)、实体、值对象精炼思考总结 netfocus 2012-02-14 17:50
帖子和回复之间的关系比较弱,不像订单和订单项一样是一个内聚的关系;
帖子和回复以及回复的回复之间就像是一个链,帖子是链中的第一个结点,回复是第二个节点,回复的回复是第三个节点;帖子如果被删除了,就是这个链的头被移除了,但这个链的后面的结点还是在那里的。
实际上你没什么理由一定要把帖子和回复内聚在一起成为一个整体的,这样做只会带来“大聚合”的各种问题,比如性能问题和并发问题。当我要发表回复时,每次都要取出帖子,然后往里面增加回复,然后保存整个帖子。在并发的情况下这是不行的。
如果帖子和回复在一个聚合内,聚合意味着“修改数据的一个最小单元”,聚合内的所有对象要看成是一个整体最小单元进行保存。这么要求是因为聚合的意义是维护聚合内的不变性,数据一致性;
仔细分析(我上面博文中分析过),你会发现帖子和回复之间没有数据一致性要求(你可以在看看我上面的分析,与订单模型的分析进行对比)。所以不需要设计在同一个聚合内。
从场景的角度,我们有发表帖子,发表回复,这两个不同的场景,发表帖子创建的是帖子,而发表回复创建的是回复。但是订单就不一样,我们有创建订单,修改订单这两个场景。这两个场景都是围绕这订单这个聚合展开的。
Re:聚合(根)、实体、值对象精炼思考总结 lcs-帅 2012-02-14 14:02
我上面的比喻还真给你说倒了.....
爹死了,儿子还真不要跟着死!!
贴子跟回复.我觉得贴子没了,那回复也得跟着没有了..
我是这样理解的...所以.贴子是根.回复只是贴子里面的一个可有可无的东东.
Re:聚合(根)、实体、值对象精炼思考总结 netfocus 2012-02-14 12:52
[quote]lcs-帅:没有帖子,就没有回复.觉得贴子就是回复他爹....[/quote]
帖子就算是回复的爹,那爹死了,儿子就要跟着死吗?
帖子是回复的爹只是说明没有帖子被生出来就不可能有爹的儿子出世,但这个关系并不能说明爹死了儿子也必须跟着死。所以,帖子和回复是独立的,有自己的生命周期,就像爹和儿子是两个人,有各自的人生一样。
Re:聚合(根)、实体、值对象精炼思考总结 lcs-帅 2012-02-14 10:41
没有帖子,就没有回复.觉得贴子就是回复他爹....
Re:聚合(根)、实体、值对象精炼思考总结 netfocus 2012-02-14 10:07
@lcs-帅
有什么地方有疑问?
Re:聚合(根)、实体、值对象精炼思考总结 lcs-帅 2012-02-13 23:51
订单模型我能理解.但是帖子和回复的模型.我一直理解不了.....
Re:聚合(根)、实体、值对象精炼思考总结 netfocus 2012-02-13 11:33
@dax.net
你也可以做一下你自己的总结,可能还是有一些不同的观点的。
Re:聚合(根)、实体、值对象精炼思考总结 dax.net 2012-02-13 10:23
@netfocus
是啊,我本来也想这周在博客中把这个问题说明一下。现在看来免啦。直接引用你的文章就可以了。
Re:聚合(根)、实体、值对象精炼思考总结 netfocus 2012-02-13 09:53
呵呵,要勤于记录,不然很快忘掉,最后没什么积累。记录下来也可以反复看,随着时间的推移知道其还有哪些不足的地方。
Re:聚合(根)、实体、值对象精炼思考总结 dax.net 2012-02-13 09:50
netfocus速度快啊,咱们刚刚讨论完,你就总结完了。哈哈!!
面向对象和面向过程只是老外提出来的一些理论。自己要正确认识。千万别盲从。有时候面向过程(函数式编程)可能对得到的大量数据处理更加流畅。加油。
Re:分享我对领域驱动设计(DDD)的学习成果 Shpix 2012-01-12 10:23
@netfocus
谢谢楼主的回复和推荐。请问有没有关于领域驱动里的统计部分的设计。我已经开始用经典的DDD了,不想立马去应用CQRS,我想经典的DDD也该能处理统计方面的问题。还有就是经常性用的的组合查询,你知道我用的是Entity Framwork,如果自己写Sql,也需要有个承载查询集合的对象,这样就会多出许多类来。
Re:分享我对领域驱动设计(DDD)的学习成果 netfocus 2012-01-11 22:30
@Shpix
1. 关于统计信息,我们不会建模在领域模型里面;统计信息只用于显示,而且统计信息各种各样,经常变化,放在领域模型中不合理。领域模型只捕捉聚合及其相互之间的关系;所以,对于帖子和回复这两个聚合,不需要为帖子上增加一些关于回复的统计信息,而只要在回复上关联一个帖子ID即可;那为什么是帖子ID,而不是帖子对象呢?答案见下面;
2. 关于User是否应该是值对象的问题。按照我的思路是这样来设计的,首先Thread(帖子),Post(回复),User(用户)三个都是聚合,每个对象都可以在自己的上下文中单独更新或创建,比如发帖,发表回复,修改用户个人基本信息,等;那么关于Thread的作者,Post的作者这样的和用户关联的信息如何设计呢?应该用聚合关联的方式还是把User设计为值对象还是其他方式呢?我的回答是,一个聚合代表了一个data consistency boundary,即一个数据一致性边界,聚合与聚合之间不应该通过引用的方式来关联,而应该通过ID关联;所以回答上面的问题就是,Thread有一个AuthorId,Post有一个AuthorId,而AuthorId就是一个值对象;这里你可能会想,那不是回到了贫血模型了?我想说的是,难道就是把Model.OtherModel变成Model.OtherModelId后就从充血变成贫血了?你觉得可以这样等同理解吗?我希望你能再仔细想想聚合与聚合之间如何建立关联比较好,多想想引用的目的,引用的本质,多想想通过ID关联的本质和其意义吧。
如果你想知道我这些想法的来源,可以参考这里提到的三篇文章:
http://www.domaindrivendesign.org/library/vernon_2011
Re:分享我对领域驱动设计(DDD)的学习成果 Shpix 2012-01-11 10:49
[quote]netfocus:
@Shpix
1. 如果回复和帖子是一个聚合内的,帖子是聚合根,那么任何与回复有关的操作都必须由帖子实现;理由是,整个聚合就是一个整体,是一个数据修改的单元。整个聚合总是被一起取出来,然后整个一起被保存,保存时必须采用完全替换原聚合的方式;这是必须的;
2. 再进一步分析这个聚合,你会发现帖子和回复不应该在一个聚合内,而应该是单独的聚合;一些对象之所以成为一个聚合的原因是什么?是因为有依赖关系?是因为生命周期的原因吗?表面上看是这样,而且大多数人觉得回复离开帖子没有意义,所以自然认为回复应该被聚合到帖子内。但是如果这样思考,说明我们没有掌握聚合的本质!一些对象聚合在一起不...[/quote]
楼主说得有道理,我现在也是这么做的,但DDD还是有好多地方没经验。还是拿帖子和回复来说[img]http://pic002.cnblogs.com/images/2012/29195/2012011110413950.jpg[/img]
这个图里面有几个问题:
1:楼主说到的回复帖子不影响帖子本身,但添加回复都将导致帖子的统计信息发生变化,如帖子的回复数,最后改变时间(用于得到最新变化的帖子),最后的回复等信息。
2:在用领域开发中,一直困扰的问题就是类似于User这种对象,有人说他应该是值对象,我也比较同意这种理解。系统中的帖子,回复,文章等等,抽象出来他们都是事物,而用户信息只作为他们的一个整体值信息,不可变性(要嘛整体删除,要嘛替换).但对一个社区系统来说,太多的User引用,如何去处理这些User?又如何把这个User值对象通过数据库重构回来。
3:由第2条问题,也就对应了楼主所说,回复不能改变帖子本身,是不是帖子在回复对象中也是一个值对象?
Re:分享我对领域驱动设计(DDD)的学习成果 artwl 2012-01-04 22:28
再次看了一遍,很有收获
Re:分享一下我买过的书,有些还没看完 zhangaz1 2011-12-30 10:59
和楼主重合度很大,比如楼主列的这几本:
代码大全
整洁代码之道
实现模式
重构与模式
.net设计规范
除了第四本没看完,其余的都看完了,请问下楼主目前做的项目是什么方向的?
Re:DDD领域模型设计之--论坛 netfocus 2011-12-20 18:55
@安度
模型只引用仓储的接口,如IProductRepository,而IProductRepository的实现在另外的dll中。
运行时通过IOC注入IProductRepository。
Re:DDD领域模型设计之--论坛 安度 2011-12-20 09:07
按照设计,存储库不能和模型分置到不同的类库中,因为这样的话,会产生互相引用的问题。而如果不放到不同的库,通过文件夹组织的方式,则会不会把领域层做的很臃肿?
按楼主分析,基本上可以分析出,没有任何的二个对象可以归到一个聚合根之下...感觉这东西要有个度,不然,我感觉世间万物没有2个东西之间一下有不变性规则....
Re:分享一下我买过的书,有些还没看完 netfocus 2011-12-15 22:39
模型之间应该按照Model.OtherModelId来建立关联的。这样有很多好处。那个源程序我还有,如果你有兴趣可以加我QQ:94388050
Re:分享一下我买过的书,有些还没看完 JimHappy#真嗨皮#郑海滨 2011-12-15 14:16
上面的书中,我们有 14 本是一样的,不过我有更多写清晰代码的书哦,比如:
代码大全
整洁代码之道
实现模式
重构与模式
.net设计规范。
楼主好像删了 “和大家分享一个我自己做的基于DDD+事件驱动的领域模型基础架构(附架构源代码和演示例子)” 博文,我正想再次阅读呢,蛮可惜,因为我在那里看到楼主不使用 Model.OtherModel,而使用Model.OtherModelId;最近在弄内存事务的时候发现了更多支持此做法的原因:
有利于 内存事务;
有利于 可空声明;
有利于 对客户端的同步;
而不利方面仅是 属性导航(变成方法了) 和 客户端显示(定义DTO) 这两个可通过多点代码就能弥补的小缺点了。
而 内存事务、可空声明 和 对客户端的同步 是我最近很关心的,楼主的做法对我来说真是神来之笔啊。
Re:分享我对领域驱动设计(DDD)的学习成果 netfocus 2011-12-14 23:16
@Shpix
1. 如果回复和帖子是一个聚合内的,帖子是聚合根,那么任何与回复有关的操作都必须由帖子实现;理由是,整个聚合就是一个整体,是一个数据修改的单元。整个聚合总是被一起取出来,然后整个一起被保存,保存时必须采用完全替换原聚合的方式;这是必须的;
2. 再进一步分析这个聚合,你会发现帖子和回复不应该在一个聚合内,而应该是单独的聚合;一些对象之所以成为一个聚合的原因是什么?是因为有依赖关系?是因为生命周期的原因吗?表面上看是这样,而且大多数人觉得回复离开帖子没有意义,所以自然认为回复应该被聚合到帖子内。但是如果这样思考,说明我们没有掌握聚合的本质!一些对象聚合在一起不是根据“谁离开了谁是否有意义”这样的思路去判断,而是看这些对象之间是否真的是一个整体,我们是否总是把它们看成是一个整体进行操作,还有核心的判断标准就是在某个界定的上下文中,这些对象之间是否有不变性规则,所谓不变性规则是指对象之间在任何时候都要维持某个数据约束规则。从这点来看,帖子和回复之间并无任何不变性规则,帖子和回复之间完全可以独立变化。帖子根本不关心它自己有多少个回复,也不关心它的某个回复有没有改变回复内容;对于回复,也只要确保其被创建时有一个对应的帖子并且我们只要确保该帖子不能被修改即可;可以看出,帖子和回复之间没有不变性规则,我们也没有把它们看成是一个整体进行处理;试想如果每次在新增一个回复时,都要先把帖子及其所有关联的回复取出来,然后把新的回复添加到帖子的回复列表中,然后在整个保存帖子聚合,那在多用户并发回帖的情况下,如果采用乐观锁定,那帖子几乎是无法被保存的。再举个列子,就是订单与订单项,一个订单包含了多个订单项,任何时候,我们都把订单和订单项看成是一个整体,并且我们也总是把订单一次性作为整体取出来,然后作为一个整体去操作它,然后作为一个整体去持久化它。自始自终都是一个整体的概念去看待它。另外,订单有总价,在任何它维护的一个订单项发生改变或者订单项有增加或减少的变动时,订单都要去关心,因为它要实时去根据某个规则去计算订单总价,所以可以看出订单和订单项之间有不变性约束;因此我们需要把订单和订单项放在一个聚合内。从这两个例子,希望能给你一些启发,关于如何确定聚合边界方面。
具体你可以看看我对DDD的建模方面的一些核心建模技巧的总结:http://www.cnblogs.com/netfocus/archive/2011/11/13/2247471.html
Re:分享我对领域驱动设计(DDD)的学习成果 Shpix 2011-12-13 16:40
如何对聚合根内的实体进行更新和删除操作,如论坛的回复,他应该属于帖子聚合根下是实体,离开了帖子,回复就没有存在的意义。但我如果的回复进行更新,传进来一个回复ID,如何得到回复呢?
代码看了,写得很好,学到好多东西
感觉这种方式对于代码的理解也顺畅很多,特别是业务上的
我还想问下,如果我需要分离客户端和服务端,
客户端和服务端通过WCF的方式进行交互,这样还需要怎么处理比较好些?
分析透彻,能基于书本,又脱离书本,善于总结思考,值得学习
Re:分享一下我买过的书,有些还没看完 yzjxue 2011-12-03 23:50
我也系统的认真的找几本书看看,学习下。1
Re:分享一下我买过的书,有些还没看完 chenping2008 2011-12-03 21:40
楼主,我买得书都跟你的差不多啊。
Re:分享一下我买过的书,有些还没看完 狼-志 2011-12-03 21:04
大哥,你的书库真丰富!
Re:分享一下我买过的书,有些还没看完 kenchell 2011-12-03 21:01
赞下lz
Re:分享一下我买过的书,有些还没看完 toEverybody 2011-12-03 21:00
neT方面的书Win8一出现后,就过时了, 因为CLR被边缘化了,由于性能问题会慢慢消失,代替它的就是WinRT,非托管程序
尴尬原来是我浏览器本来就缩小了
可能平时不小心按到鼠标滚轮+ctrl
还好浏览器有缩放的功能呵呵 第一次觉得这还是有用处的。。
学习了~~
不过字体太小成片好晃眼啊看着好累
简约是好,但影响到根本的阅读了。
Re:关于软件的任务到底是什么的思考 永远的阿哲 2011-11-21 16:50
个人感觉还是构造一个独立的领域模型较好,这样就可以不依赖外部的执行环境而进行复用.
我也写了一篇简单的博文,班门弄斧了~~~
http://www.cnblogs.com/ljzforever/archive/2011/11/20/2255712.html
最近在学习四色模型,看到这个讨论也想说2句:
1,如果图书管理员关注的是本校学生可以借书,
学生(ppt)以本校的学生(role)借书(mi)
模型中没有借书卡
2,如果图书管理员想引入借书卡这种媒介,
学生(ppt)以借书卡拥有者(role)借书(mi)
领域模型中有没有借书卡这个对象,应该由实际需求决定的吧。
Re:分享我对领域驱动设计(DDD)的学习成果 netfocus 2011-11-05 11:05
@JasenKin
是的,其实,要想真正让领域模型可以很好的运作,需要有一个保证,那就是需要让所有的对象都在内存中,而不是需要时从数据库取,所以以后的发展方向可能是DDD+In Memory架构,我们可以用Redis,encache,disruptor,memcache,mongodb这些分布式高并发的存储框架为DDD提供对象存储支持。
Re:分享我对领域驱动设计(DDD)的学习成果 JasenKin 2011-11-05 10:41
DDD,成也领域模型,败也领域模型。
Re:分享我对领域驱动设计(DDD)的学习成果 JasenKin 2011-11-05 10:20
模型(实体)与服务(场景)是对领域的一种划分,模型关注领域的个体行为,场景关注领域的群体行为,模型关注领域的静态结构,场景关注领域的动态功能。这句非常清晰地概述了模型与场景的用途,非常不错。
个人认为,从整体来说,领域模型必须先设计全面才能进行下一步操作,不然所受到的影响将非常大,受限于领域模型的构建。
Re:关于软件的任务到底是什么的思考 Trace.wu 2011-11-04 13:12
我以及我的一群朋友,对SOLID,GRASP,……面向接口编程……等等一系列原则定义为——咒语,这些咒语需要我们时刻念叨。正如上面我说的,没有最好、最坏,只有合适不合适,我们在做分析、设计时,念念咒语,告诫自己要遵循这些道道,做出来的东西才可能具有较好的价值。
Re:关于软件的任务到底是什么的思考 Trace.wu 2011-11-04 13:09
贫血、充血。不一定说死谁好、谁坏?只有合适不合适而言。但从OO的角度来说,一个对象仅有数据而没有行为,是一件非常诡异的事情;同理,一个对象仅有行为没有状态(数据),也是很奇怪的。但奇怪只能说明,你的设计是否该修改,该改进,而不一定你的设计就是错的。
任何问题,都有上下文,都有具体的背景。但这些“咒语”,能够时刻告诫你,设计时遇到这个现象,你就该多思考一下,是否合适。
Re:关于软件的任务到底是什么的思考 Trace.wu 2011-11-04 13:06
@netfocus
我严重的支持你,你的绝大多数观点,和我这2年的感悟完全一样。没有真正理解OO的人,是难以感悟DDD,TDD等一系列思维的好处、差别。
Re:关于软件的任务到底是什么的思考 诺贝尔 2011-11-03 13:34
不要英文不行么?
Re:关于软件的任务到底是什么的思考 淫光初学者 2011-11-03 11:23
喜欢充血 这个不解释