关于领域驱动设计的一些疑问

14-01-02 Awaken
早在一年前就有听说过jdon,近期又对banq给出的几个例子结合框架(jdonframework)源码读了一下,对于jdon的核心思想->领域驱动建模(Domain Driven Design)有些粗浅的理解。我个人的认识是:

1.领域,即业务模型,如banq给过的两个例子:比赛、机器人。这里的业务模型又包括业务对象、对象行为、对象状态。

2.驱动,即事件驱动。这里我将业务对象的行为理解为事件,也就是业务对象的行为(或动作)操作定义为事件操作!

以上理解,不对之处,还望各位走过、路过的大大们不吝拍砖(指正)!不胜感谢!

额?。。。不好意思,可能说的不是很清楚!

我的疑问:

1.看了几个例子,感觉DDD的思想代码里面诠释的很清楚了,不过貌似里面对jdonframework的应用好像很少(不知道是不是我理解有误)。感觉和别的框架很大差异,不是很清楚jdonframework的定位是干什么的?(像经典的hibernate、struts、spring等,还有快速开发框架springside等都有明确的定位!或者说它们给出的范例更多、更全面!)仅仅只是推广DDD设计思想吗?(希望大大们能够不吝说明下!非常感谢!)

[该贴被Awaken于2014-01-02 19:21修改过]

                   

3
banq
2014-01-02 19:47
>这里我将业务对象的行为理解为事件,也就是业务对象的行为(或动作)操作定义为事件操作!

你的疑问可能和这段理解有关,对象的行为由事件触发,但是不代表两者是同一个概念。

如果你区分了对象的行为和事件,那么就会思考事件到底是什么,其实在传统技术架构比如SSH中,我们的对象行为是被用户的请求触发的,用户的请求提交给Struts,然后通过Struts 的Action提交到Spring的服务,调用服务的一个方法行为。

这个思维方式是一种请求/响应思维,而我们现在要以事件替代请求/响应(request/response),这就是EDA最大不同。

因为思维方式不同,那么肯定有不同的框架,Jdonframework就定位在事件角度。

上面流程就变成:用户发出一个命令command,被富领域模型的行为接受处理,在这里会有多个命令操作同一个模型的同一个状态的问题,一般要引入堵塞锁,Jdonframework通过Disruptor的队列实现某个时刻只有一个线程调用模型的行为进而修改状态,非堵塞无锁。

第二点,当模型中的状态被修改以后,会有一个事件触发,称为领域事件,实现EventSourcing,关于DDD和ES的关系见:http://www.jdon.com/46041

除了对业务的思考方式不同,技术特点也不同:

比如在一个典型SSH应用案例中,用户界面中的用户请求(在浏览器中,REST客户端或其他地方)发送到web层进行解析,然后分发到中间件服务组件,通过它的高速缓存然后下推到数据库。如果这些层中任何一个层都不参与以下操作:阻塞调用数据库,依靠共享的易变状态,使用昂贵的同步操作进行调用,那么整个请求处理响应的流水线就不会停顿,用户就不会将遭受延迟通过增加和减少的可扩展性。

An application must be reactive from top to bottom

一个应用必须从顶层到底部都是reactive的。

http://www.jdon.com/45811#23143632

Jdon框架提供了整个技术堆栈都是可异步和高并发的。

[该贴被banq于2014-01-02 20:00修改过]

Awaken
2014-01-02 20:12
感谢banq大大的不吝指正和解释!

嗯,对于您刚对事件和行为的回复,我可不可以这样理解:

(举传统的例子)

>“......在传统技术架构比如SSH中,我们的对象行为是被用户的请求触发的,用户的请求提交给Struts,然后通过Struts 的Action提交到Spring的服务,调用服务的一个方法行为。”

上面说的“用户请求”即是事件,通俗点讲就是:用户在页面点击某个按钮或链接(点击是行为!),触发请求提交给后台.....(这里请求是事件!)

不过,我感觉行为和事件有点难以区分(可能习惯性思维),像上面:用户在页面点击某个按钮或链接(点击是行为!),触发请求提交给后台.....(这里请求是事件!).....,后台控制层调用action层,action调用service服务层处理方法(这里又是一个行为)....

(行为和事件)它们之间的界限貌似不是很清楚,如果不注意的话。

banq
2014-01-02 20:36
请求 行为和事件都是有区别的。

请求和响应是一对,谈到请求就要有响应,请求不能单独存在,就象谈到服务就有客户端一样,两者是配对的模式。

问题来了,因为请求和响应是一起的,所以谈到请求就必要有响应,而实际中有时请求只需要有一个http 200的响应就可以了,这时响应就没有意义,就剩余请求了,这个请求就蜕变成事件了。变成事件的好处是,原来请求必有响应其实是同步,而没有响应的请求其实是异步,异步并发概念可以引入了。

请求(事件)在多层之间传递时,身份其实有改变的,在进入聚合根实体模型之前是命令(有时也称为事件 比如UI的javascript点击按钮也称为事件),改变实体对象状态后是领域事件,也就是在领域中发生的事件,不是UI发生的事件。

行为是对象的能力,打个比喻,如果把行为看成是炸药的引子,那么事件就是点燃引子的火种。行为是在我们设计类时根据业务特点设计好的,而事件是在运行时才产生,事件类似交互的行为,而普通行为是对象职责行为,按照单一职责SOLID等等设计的。

行为是静态的,事件是动态的。

在事件驱动场景下,一个用户发出命令要修改聚合根实体模型的状态,这个命令是通过守护状态的行为实施的,打个比喻,状态是宝贝,守护行为是警卫,大盗是通过警卫才能取得宝贝。在事件驱动情况下,这里我们引入单写原则,同一个时间只有一个线程修改状态,虽然锁也能达到这个目的,但是我们这里没有用锁,而是如何让Java以光的速度跨线程通信中的Railway算法或RingBuffer算法,而传统请求/响应模型,这里引入的是 ACID事务,比如 JTA(Spring or EJB session bean) 或者使用HHibernate/JPA的乐观锁rOptimistic lock(Hibernate/JPA)。两者比较见:http://www.jdon.com/performance/singlewriter.html

[该贴被banq于2014-01-02 20:48修改过]

Awaken
2014-01-02 20:56
嗯!您的解释很形象!感谢!

额,不过这里吐槽一下,感觉一下子从以前的思维方式很难转变过来。。。直接的感官就是DDD设计的有些东西好难理解!(纯粹个人观点,我不知道别人有没有相同的感觉!)这样就对接受这种设计方式很不适应,或者感觉很难上手!希望banq大大不要介意!

嗯,这里还有几个问题:

1.既然架构设计方式都变了,那么以前的那种mvc的分层式结构还能用吗?如果不能用了,现在怎么办?(因为我发现在jdon官方给的例子里面好像是没有的?)

2.ES事件溯源,感觉有点像workflow工作流,能向前、能后退....。这样,ES好像都是保存在缓存中的,那么当这种以事件为核心的架构,保存的事件数据会不会很多?另外,保存在缓存中会不会有丢失的危险?(我的认识缓存之所以应用广泛,保存在内存中便于快速读取是一个很大的优点。可能认识有误!)

猜你喜欢
2Go 1 2 下一页