大家看看我设计的这个关于图书馆借书还书的模型属于贫血还是充血?
之前大家也都对图书馆借书还书的例子讨论很多了。所以业务需求描述我就不多说了。直接贴代码吧。
下面代码的实现基于我自己开发的一个EventSourcing框架,继承自EventSourcing<T>类的表明是一个事件源。
|
之前大家也都对图书馆借书还书的例子讨论很多了。所以业务需求描述我就不多说了。直接贴代码吧。
下面代码的实现基于我自己开发的一个EventSourcing框架,继承自EventSourcing<T>类的表明是一个事件源。
|
|
|
|
|
|
|
可能眼花,没看到BOOK实体,只看到bookinfo值对象,还有一个BOOK是继承eventsource,如果它是实体,不应该和事件源直接耦合,因为事件不只是创建,还有其他涉及各种场景的不同事件,应该是角色直接和事件耦合。
事件驱动和service结合在一起,实体比如BOOK或图书馆这些数据模型是被操作,被强奸,而不是实体去指挥驱动事件和服务。真正ddd+event source是突出以聚合根为中心,你这些代码是以服务或事件为中心,只能是event sourcing系统,没有ddd, 这是我个人对你这些代码的认识。
好!非常期盼能看到banq写的针对这个例子的真正的DDD的实现,另外也非常希望能看到banq是如何使用JdonFramework的,以及如何让领域对象处于核心地位,非常期盼。相信大家也和我有同样的感觉,我现在只想用成套的模型设计来说事,总是理论一大堆,没有产出,不能信服于人。大家把自己认为好的模型设计拿出来,至于谁好,我相信后人看到自会公论的,呵呵。
讨论需要理性,可不能赌气哦,没有谁高谁低,只是在分享讨论中大家共同进步。
jdonframework案例都是以DDD为核心,这里有一个现场案例Robot,案例开发说明见:
Robot案例开发说明
源码下载见
https://github.com/banq/jdonframework/tree/master/examples
等我有空再写这个图书馆案例,应该可以从Robot案例推导出图书馆案例怎么写。只是想抛砖引玉,不想流芳百世,让人验证考验,我做我想做的。呵呵。
那好吧!我实际也不是想和你赌气,而是希望能看到您的解决方案而已。
因为您总是说的很高深,而我的代码不是DDD,所以我非常期盼你能写出DDD+DCI+Event Sourcing+JdonFramework的例子出来。
我强调的是任何设计和代码都要“自然”,如果你写出来的确实是如此,大家自会信服的。
呵呵,其实我追求的不是让大家信服,而是让你这样的高手让大家信服,这也是我非常欣赏你的作品,但是又如此犀利指出与我理想中的不足,如果一个比较好的思想不只是我一个人实现,还有众多你这样高手都能实践,这才能普及这样好的思想,才能让更多人受益。
这些好的思想很多不是我原创,我只是做了点落地工作,希望筑巢引凤,让中国人设计水平提高起来。届时也是我退休之时,呵呵。
[该贴被banq于2012-09-17 13:48修改过]
晚上看了banq提供的关于机器人的例子,该例子结合了DDD+DCI+Domain Event,但是没有用到Event Sourcing
要是我之前没学过DCI的话,估计一定看不懂,呵呵。
下面是我对该例子的一些理解:
1. 在DCI架构下,DDD中model可以非常瘦身,只需要有描述model自己的固有属性即可,这就是DCI中的data;
2. 场景相关的交互行为由role定义,通过roleManager.assign(model, someRole)来让对象动态赋予某个角色所赋予的职责,但是通过model.ActAs<SomeRole>()这样的写法不是更清楚吗?这样连roleManager都可以不需要;
3. model不是被保存,而是主动扮演角色通知别人保存自己;有意思的是你提到由于可能保存操作比较耗时,所以采用了异步的domain event来通过发送消息的方式来让repository保存model;
4. model进入场景(context),扮演相应角色,然后角色之间行驶交互逻辑;然后context有上层界面创建并启动context中的交互行为;
不知我的理解对不对?
下面是我的几个问题:
1. 如果要引入Event Sourcing,那ES应该是应用在model上还是role上?我想应该是model上吧?那如果model采用es,那model中的所有修改数据的行为就会产生相关事件吧,并且这些事件应该不是你robot机器人中的domain event,对吧?那你能解释一下event sourcing中的event 与domain event 的区别和联系吗?
2. DCI中的role会有与该角色相关的状态吗?如果有,那角色的状态如何持久化,如何重建,特别是在采用ES架构的情况下;
3. 场景的交互结果如何表示,也用model来表示吗?如果用model表示,那保存时也用你机器人例子中类似的方法吗?如果用了es,应该不能采用这样的方法吧。
ES显式是没有用,因为这需要巨大存储库,实际你只要把Domain Events作为事件源保存起来就实现ES了。具体参考jdon framework 为什么没有用Event Source 呢说明了。
推荐你看看这个javascript的Node.js应用案例:采用cqrsnode框架开发的DDD CQRS例子,也是围绕领域模型为核心,Javascript和Java等基本都能实现,相信.NET也可以实现。
简单回答一下你的几个问题:
1. 如果引入ES,当然是在Role上,如果是在Model上,不是和你现在代码一样,两种耦合在一起了?总结公式如下:
Data Model => Role/Context <=事件交互行为
2.角色与状态无关,状态是Model内部的字段或属性。
3.交互事件的结果也是落实在Model内部字段和属性上,持久化保存也属于模型扮演角色的一个功能,这个角色称为负责保存的角色,什么是角色?有职责的角色,什么叫有职责?就是应该做什么事情,比如你担任家长角色,就有负责家庭的职责,你担任公民角色,就应该负担公民的职责。
ES只是属于角色应该实施的一种交互行为,也属于DCI的I交互行为。
什么是事件?事件和行为方法有什么区别?
事件是涉及两个平行独立对象以上的行为,而方法行为没有这个规定,可以是对象自己的方法行为,也可以是调用其他对象的方法行为,后者称为交互行为,也称为发送事件或消息。
参考:
Eric Evans关于技术如何影响DDD的会话
[该贴被banq于2012-09-19 09:10修改过]
针对你的回复我有产生了另外一个问题,我问题总是比较多,呵呵。
ES是作用在role上,能在具体点吗?我的疑问是,如果domain event应该由role驱动发出并持久化,这点我没异议。那我们重建的应该是聚合根(DCI中的data)还是role呢?肯定不是role吧,因为role是无状态的;那就是聚合根了,但是奇怪的是聚合根根本没发出过事件,它有怎么会“认识”它之前所扮演的某个角色所发出来的事件呢?事件应该只有role才认识。当然,你会说,聚合根扮演角色后,实际上聚合根与角色是一个东西,不能割裂开来看。这个我赞同,但这里体现出了不对称性。即发出事件的是role,而利用事件重建的是聚合根;这里的根本问题是,我们重建对象时,重建的是聚合根,而不是“聚合根扮演某个角色后的东西”。
希望能清楚回答一下你对这个问题的理解!