对DDD与DCI的突破性思辩

我来用简要的描述一下DDD和DCI的突破性思维。为什么需要DDD / MVC / DCI ,其实是对人类思维可控性的考虑。我们需要着重于DSL思维,要更加靠拢需求和用例。而DCI的提出让OLD DDD 重新考量,而让DDD提供了必要的几个概念,而这些概念也是为DCI框架提供的工具。

我们不能让DDD的一些概念绑定住,要突破并在实际开发中融合这些工具到实际的项目中来;前提是不能为了DCI而DCI,更不能为了DDD的概念而DDD。记得以前J2EE的发展历程,就是个悲剧。”山寨“的spring更迅猛的超过了”规范“。

四色 DDD DCI 融合起来后,包括CQRS,我们必然要舍弃改变和突破一些东西。比如Service,我个人认为可以让DCI中的角色的行为来代替,而DCI中的角色不一定要有领域实体充当。如下:


var role = new Role( /*这里可以不必注入entity*/ );

另一方面,我觉得场景中的必须是角色交互,而不是领域实体的交互。场景属于DSL的思考层面,更接近于需求和用例。而领域也是伟大的出现,但是不能为了领域而领域,为什么呢?因为场景是大哥用例是大哥。领域的存在是为了控制固定概念的部分,这样在某种成度上控制了一定的复杂性和提高了可控性,DCI解决了可变性和需求的问题。从某种意义上来说,“领域层(在DCI中可能不会太凸显领域层,不如OLD DDD那么凸显)” 是为了 DCI架构 服务的

[该贴被liontseng于2011-05-11 15:42修改过]

写得不错,目前有多种思想在激烈交会。
color uml and dci 的问题一种思想认为“角色”是主观的东西;楼主的观点是在场景中主要是角色参与行为。

对于DDD和DCI关系,可以认为DCI是对DDD深化,更加接近需求用例,DDD可能应该是对DCI中Data部分的一个细化分支,DDD中对场景只是轻描淡写用限界上下文,bounded context带过,DDD认为场景是领域模型的背景,生存环境,这点与DCI中对场景的认识应该是一致的。

而不同之处在于:领域模型是通过角色扮演存在场景中,而DDD没有对领域模型如何和场景互动进行进一步说明,可以认为DDD是从结构上确定了领域模型(DCI中的Data)和场景两种静态构件,而DCI更如同行为型模式一样着重了领域模型(DCI中的Data)如何通过角色的套子实施场景相关的行为,是对偏重于静态特性的DDD的一种发展和突破,也是符合“职责驱动开发”中对象职责的认识。

所以,DDD可用之处在于其实体以及聚合边界部分,至于其所谓领域服务service,因为它是一个静态结构方法,所以对service也是笔墨不多,楼主认为可以用DCI角色行为来替代,我认为也可以用场景来替代service。使用哪种方式替代,关键还是看需求用例。

我个人认为:DCI场景非常好地和需求分析的四色原型mi相吻合,也和需求表达方式:用例图,更贴切,用例图本来就是一个功能场景角色的关系表达图,可以和DCI直接映射,比较自然,这样,需求到技术转化就很直接,没有过多专业技术和方法参与翻译,这样做出来的系统更符合需求,也能更紧跟需求变化。

当然,理论上任督二脉打通了,实际落地时,还是有很多细节问题,也不知老外躲在哪个角落在讨论这些实质细节问题,但是我们自己总得也动脑权衡其中利弊,大家放开思维辩论是必须的,没有谁对谁错,创新领域经常发生:有心栽花花不开,无心栽柳柳成荫,谁能说了算呢?


[该贴被banq于2011-05-11 17:39修改过]

呵呵,banq的回复很中肯啊。我们还要多思考啊,不能落后于老外,至少在思想上不能落后。现在感觉领域模型的静态组织结构比较好想通,基本上Evans Eric已经帮我们都整理好了,但是如何实现动态的部分,即如何让这个静态模型动态起来,如何让各个对象动态地和场景进行交互,是个难点。我之前说是PPT在和场景进行交互,楼主说是Role在和场景交互。每个人都有自己的理解。就像banq所说,这是思想的碰撞。我们要好好再思考,希望能有更多这样的帖子出来,讨论动态交互的部分。大家好好努力呀。

DCI能很好对应用例是我很欣赏的地方。但这就要注意用例分析的正确性,也就是用例图本身要符合逻辑。例如,登录是不是用例,是的话他是由谁执行?这些看似简单的问题往往最能考验用例图逻辑一致性。当解释不能,或者逻辑冲突的时侯,就需要怀疑这用例分析了。

PS:给大家一个问题,只需思考,不用回答,登录是不是用例?是的话它依附谁?这用例与业务相关的用例不同点是什么?

虽然不用回答,我也说一下我的观点。

问:登录是不是用例?
答:可以是。也就是一个场景。

问:是的话它依附谁?
答:依附谁?这个问题应该是如果是一个场景的话,登录的场景是有哪些角色参与的;答案当然是“登录者角色 loginRole”和“验证者角色 validatorRole
场景的内部代码类似 ->

 validatorRole.validat(loginRole,callback); 

当然,我上面的不是绝对答案,只是举例而已,概念上和命名可能不准确。(道可道非常道 名可名非常名

问:这用例与业务相关的用例不同点是什么?
答:这个是主观的,登录也是一种业务,难道不是吗?

[该贴被liontseng于2011-05-12 11:42修改过]

其实我觉得场景可以化为无形。一个场景都是某个事件引发的。比如登陆的例子,用户输入用户名和密码要求登陆,此时其实可以理解为发生了一个登陆的事件,该事件包含了一个目的(就是某个用户要登陆),并且该事件也携带了一个消息,该消息包含两个信息:用户名和密码。但是事件和消息是一体的。
我们可以用类似下面的方式来定义登陆的事件:


public class LoginEvent
{
public string UserName;
public string Password;
}

然后,有一个或多个关心该事件的“人”会响应该事件,在登陆这个例子中,就一个响应者,如下:

public class LoginService : ICanHandleEvent<LoginEvent>
{
public ValidationStatus Handle(LoginEvent evnt)
{
//get userName and password to do the user validation.
//and then return the validation status.
}
}

最后要做的就是将事件和响应者建立关系,这个过程的作用相当于你实例化场景的过程。

这样做有什么好处,相比于只能静态的接受参与者个数固定的场景而言,事件能够灵活的增加或减少场景参与者。事件和响应的做法相当于将一个场景要做的工作分散到了每个参与者(这里我们不必讨论参与者到底应该是PPT还是Role),我觉得这种设计更加体现出事件参与者的主动性,更加能表现出OO,因为这体现出各个对象在协作完成一件事情。而楼上提到的场景的内部实现其实本质上还是一种面向过程的方式,你先搜集所有的场景参与者,然后一步步调用每个参与者的方法,这本质上就是一个面向过程的思维。
[该贴被tangxuehua于2011-05-12 13:12修改过]
[该贴被tangxuehua于2011-05-12 13:13修改过]

2011年05月12日 13:00 "@tangxuehua"的内容
然后一步步调用每个参与者的方法,这本质上就是一个面向过程的思维 ...

仅仅是这样就被认为是面向过程?

难道不是吗?

关于你的事件响应方式,可以在某些技术实现方面适用,而对于实际的框架还是应该按照DCI方式进行处理,尤其是对于中大型项目,你这种思维模式适合于小型的或UI的处理。
[该贴被liontseng于2011-05-12 15:35修改过]

2011年05月12日 15:34 "@liontseng"的内容
关于你的事件响应方式,可以在某些技术实现方面适用,而对于实际的框架还是应该按照DCI方式进行处理,尤其是对于中大型项目,你这种思维模式适合于小型的或UI的处理。 ...

为什么?

我的意思并不是说你的这种方式不好,完全可以采用。
我的意思是这样做并不能做大型的需求实践,单独的在一个登录这样的用例场景上可能可以这样实现。
同时我们要从复杂业务上来说

也许你是对的,但不能让我信服。因为没有足够的证据说明只有你的才能支持大型项目。而基于事件消息的系统就不能支持大型系统。

不是的,我的意思是,单独的事件这种形式或者说技巧,是很好的联络方式,但单独的这一个概念是不够的,必须要采用 DDD DCI 的架构合力起来的概念,然后配合EVENTS 的配合才行。

而单独的事件驱动,是很底层的东西或者说是很纯粹的东西,不可能只用事件的方式开发出大型系统来。

DDD DCI CQRS Events配合起来是可以的;这个也是未来的趋势。Events在整个这套框架中起到了消息传递和链接的方式是很好的或起到其他的作用。

不可否认你的想法也是不错的。另外我说的也不是属于我的,DDD DCI 的架构是大牛们提出的,我们要做的是让这些思维模式和概念落实到代码中,或开发出一套这样类似的框架来。
[该贴被liontseng于2011-05-12 17:22修改过]

关于事件消息在UML的用例图中也可以找到,用例或顺序图UML的带箭头直线都是一种消息。

我今天突然想到,DCI三个事物之中是没有角色Role的,我们引入角色好像和四色原型有关。这里面有些乱啊

重新查询wiki对DCI定义:
The paradigm separates the domain model (Data) from Use cases (Context) and Roles that objects play (Interaction).
http://en.wikipedia.org/wiki/Data,_Context_and_Interaction

可以看出:Data = Domain Model; Context = Use cases 用例;而Interaction =角色的行为。从这个定义也能得出DCI与四色或者用例比较接近。

context接近use case或scenario, 是map these Roles into objects at run time and to enact the use case。可以看出,它是一种在运行时刻将角色映射进入对象,如果知晓用例图,这点就非常容易理解。

相关讨论:
DDD的Service用DCI的替代方式

基金领域的DCI


[该贴被banq于2011-05-13 11:00修改过]
[该贴被banq于2011-05-13 11:16修改过]

对于DDD和DCI,在我看来无非是“偏静”或“偏动”罢了。我更希望是“静”和“动”的完美统一。