DDD聚合体作为模块的示意图

贴图:领域驱动DDD聚合体作为模块,聚合体外使用事件消息,聚合体内封装了状态,外部调用必须通过消息事件实现,而不能直接通过方法调用。

[该贴被banq于2012-12-06 12:01修改过]


2012-12-06 11:55 "@banq"的内容
贴图:领域驱动DDD聚合体作为模块,聚合体外使用事件消息,聚合体内封装了状态,外部调用必须通过消息事件实现,而不能直接通过方法调用。 ...


聚合体只是一个“分”而治之的具体表现而已,与分函数、分文件、分模块、分系统没有什么区别最终还的结合场景,具体问题具体分析,感觉不应该有什么固定的技术套路

2012-12-08 13:40 "@clonalman"的内容
聚合体只是一个“分”而治之的具体表现而已,与分函数、分文件、分模块、分系统没有什么区别最终还的结合场景,具体问题具体分析,感觉不应该有什么固定的技术套路 ...

聚合体是靠近领域的,我觉得会受逻辑影响,而逻辑又来靠语言来描述和传达。若果“编程语言”对应“聚合体”的话,我觉得“交流语言”对应“领域”,例如我们建模经常去引用领域中的“专有术语”。编程语言与交流语言之间有一定映射关系的话,聚合体和领域之间也应该有这种映射关系。不过本来的,聚合体的划分主要不是以技术差异为边界的划分,他的固定套路不是表现在技术上,而是领域中的逻辑,又或者蕴含在交流语言当中的逻辑。

2012-12-08 22:10 "@SpeedVan"的内容
聚合体是靠近领域的,我觉得会受逻辑影响,而逻辑又来靠语言来描述和传达。若果“编程语言”对应“聚合体”的话,我觉得“交流语言”对应“领域”,例如我们建模经常去引用领域中的“专有术语”。编程语言与交流语言之间有一定映射关系的话,聚合体和领域之间 ...


"外部调用必须通过消息事件实现,而不能直接通过方法调用。"
何解?

象消息事件只类,一般我只用在平行不同包之间或低层包调用上层包之间,同一包之间或上层包调用低层包为什么不直接调用,而通过“消息事件”调用只是一个技术手段而已。
(这里的上层、低层不是系统架构的而是领域层里的细分,同一包了可能有若干聚合体)

简单或极端的情况,一个系统的领域模型都在一个包里,你觉得还有必要有"消息事件"之类的吗?
我直接交叉引用不是来得更爽(或导航引用或数据引用,都直接调用)

编程语言与交流语言的范围与我们做需求是一样,要用户描述的东西其实只有一部分是系统真正要的,其他的都是天马行空,没必要强行把他们映射起来。

[该贴被clonalman于2012-12-09 06:50修改过]

2012-12-09 06:35 "@clonalman"的内容
同一包之间或上层包调用低层包为什么不直接调用,而通过“消息事件”调用只是一个技术手段而已。 ...

  在我看来“消息事件”不仅仅是一种技术手段,而是一种“技术组织构件”。另外再次强调,DDD是解决复杂业务逻辑设计问题。用DDD去设计简单业务场景问题简直是“杀鸡用牛刀”,搞错了对象。
  打一个可能不太恰当的比喻,如果你是一个小组长,可能“面对面沟通”(类似“直接调用”)就能解决所有的问题;但如果你是一个大公司领导,完全采取“面对面沟通”的方式肯定会疯掉的,必须要有一种“消息传递"机制。
  从上面那个比喻可以看出,聚合体类似一个最小的”组织单元",这个单元有个领导(聚合根),而这个单元与外界通讯的方式就是“事件”。

2012-12-09 06:35 "@clonalman"的内容
"外部调用必须通过消息事件实现,而不能直接通过方法调用。"
何解?

象消息事件只类,一般我只用在平行不同包之间或低层包调用上层包之间,同一包之间或上层包调用低层包为什么不直接调用,而通过“消息事件”调用只是一个技术手段而已。
(这里的上层 ...

用不用消息事件,那是技术方面,我也明确说这种划分跟具体技术存在很少关联,为什么我们这么敏感名词,谓词等,是因为我们脑内某种逻辑在作怪。而我们交流语言和编程语言都是为了表达逻辑,他们肯定存在一种映射,否则我们也不能判断是不是在表达同一个东西。

我想说的是聚合体的“分”,跟分函数和分文件根据的东西不太一样,一个主要受领域认知约束,一个主要受硬件约束(当然也有融合领域认知的,如JAVA的类名与文件名,这又是另外一个问题了)。

对于没有固定技术套路,我是认同的。


[该贴被SpeedVan于2012-12-09 23:13修改过]

对于交流语言与编程语言的映射,这个肯定存在的。或许程序猿自身不留意而已,对于那些为什么对一个极为相似的操作为什么不能统一、新增的东西没法融入旧有的、某些地方很微妙,却又说不出原因或说不出到底发生什么,诸如此类。这是因为没有映射起来,没有一一对应的话,怎么把逻辑一个个传递,一层层传递?对于不想牵一发动全身的,这更为重要。当然也存在过为了效率而破坏整体逻辑,于是破坏的部分就成了死结——语言已经无法描述,这一部分已失去扩展能力,这个现象在取巧的时候出现甚多。

2012-12-09 06:35 "@clonalman"的内容
要用户描述的东西其实只有一部分是系统真正要的 ...

以前我是这么认为,现在不了。

我认为:觉得要用户描述的东西只有一部分,是因为有很多东西我们已经认知,或者自以为是

可能你说的系统不是建模,对我来说用户描述的东西就是我建模的全部,自以为是的板。。。过去的我撞到鼻肿了。而且聚合体是领域概念,放到整个系统去考量不对吧。

大家说的都有道理。我谈谈我的思考:

不知有没有注意到,这张图中Cargo和Handling Event之间是通过Handled发生依赖,从业务上讲,Handled是一种发生过的装卸事件,那么如何在计算机软件中表达这种事件呢?

软件技术中的调用分两种:同步调用和异步调用,两者区别是前者在调用时同时等待对方处理结果,这从日常生活中看,表现为猴急,你也得容别人想想再回复你啊,有些简单的事情可以立即处理回复,但是复杂的事情只能表示已经收到,至于如何处理,处理结果是什么必须再等待下一步。所以,同步调用很显然不合适处理复杂大任务。

模块之间的调用常常是大任务,否则模块自己内部就消化直接做了,格式转换,时间获取,这些直接处理即可。

模块化一直是很多语言的弱项,Java中的OSGI搞了好长时间不了了之,我认为关键问题是,模块化和功能有关,所以,我们试着在建模语言与实现系统中探索模块化一种固化模式,这也是在发明设计模式,也是一种探索,是否成功不好说。

为了表达业务上的Handled事件,我们使用软件中的消息模式,其实也就是观察者模式来实现事件的发生和传递,而传递的内容正是业务Handled事件自己,消息机制如同信封,信封中包含的是业务内容。
Listener和Observer有什么本质区别吗?

消息作为信封,信封内容是事件,这种异步机制是聚合根与外界交互的最好方式,在松耦合上要好于聚合根直接暴露自己的行为或者Hold其他聚合根,能够更加严密保护自己内部状态不被外界侵入。


[该贴被banq于2012-12-13 11:01修改过]

2012-12-10 20:20 "@banq"的内容
模块之间的调用常常是大任务,否则模块自己内部就消化直接做了,格式转换,时间获取,这些直接处理即可。 ...

是否需要区分,模块内聚合根之间的调用关系与模块之间聚合根之间调用关系?
我是比较认可事件用模块间聚合根的调用,模块内部的话,该怎么办就怎么办