2012-12-22 16:02 "@gameboyLV"的内容
开始和结束的动作放在Entity里是肯定的,但是动作的内容放在哪里好呢?
直接写在Entity里感觉不优雅,而且耦合度太高。写在仓储或者服务里更加不靠谱了,理论上Entity应该在仓储或者服务的下层才对。
想来想去,还是写在独立 ...

我看axon是将开始和结束这类动作没有放在Entity,我理解Entity是实体,对于一个DB表,而应该放在领域模型中,axon中领域模型需要继承AggregateRoot,操作的内容也是放在领域模型内,由handleEvent方法负责处理,而CommandHandler是用来接受Command的,然后就调用领域模型处理业务逻辑,如果业务逻辑变化了,是不是考虑继承领域模型,复写原来的方法实现呢?

不好意思,可能是我没有描述清楚。我说的Entity就是领域实体,和数据库表对应的我一般叫DataEntity或者ValueObject或者POJO

实体和数据对象的区别就是:实体有行为和状态,能独立的表达某项事务。而数据对象(POJO)则不能。

按照我之前贴子的说法:
Repository接收Query对象并返回Entity,对Entity执行CUD操作引发Command,Command到达事件总线之后通过反射动态创建BO并处理业务逻辑。
[该贴被gameboyLV于2012-12-22 18:38修改过]

2012-12-22 17:16 "@cloudstack"的内容
也就是说CQRS是为了贯彻正常的逻辑思维,模型应该如何设计 ...

CQRS是为了更好将DDD与现有技术架构结合而推出的一种分离架构。领域专家强调领域模型要充血,不能被技术架构绑架,我们当然应该首先满足,但是数据库成熟强大的查询能力我们也不能走极端弃之不用,因为我们的系统不但要满足领域专家,而且还有用户要求的各种复杂查询功能。

我们进行仔细分析就会发现:领域模型的各种职责行为是靠用户命令触发的,没有用户的命令,这些领域模型的职责不会被激活,就像地雷虽然有爆炸功能,但是没有点爆命令也无法起爆啊。

而用户需要的各种数据组合是一种查询,这些可以依靠数据库查询能力或一些大数据框架来进行并发计算。

这两种路线其实不矛盾,于是Command和Query分离,领域专家和用户两个需求都能满足,皆大欢喜。至于为什么引入事件,因为Command和Query是两条路线,command经常导致状态变化,这种变化要及时反应到Query中,通过异步事件将两者同步。

所以,你会发现,CQRS来龙去脉其实和DAO数据库一点不搭架,两者没有可比性,服务的目标不同。如果从数据库的读写上看出共同点,那么也是一种巧合而已,因为大家都需要数据库,区别是:一个因为需要就依赖,一个只是需要利用一下而已。

2012-12-22 17:40 "@cloudstack"的内容
我看axon是将开始和结束这类动作没有放在Entity,我理解Entity是实体,对于一个DB表,而应该放在领域模型中,axon中领域模型需要继承AggregateRoot ...

我没有看Axon这个例子,但是按照DDD来理解,一个聚合根实际就是一个实体,就像一个局长实际也是一个人而已,聚合根只不过是其担任聚合之首的职责。

如果Axon将这两者分离,要么你理解有误,要么它只是一种CQRS框架,而不是严格意义上的DDD+CQRS框架。你可以参考Jdonframework的案例,聚合根与实体是合并在一起的,在DDD中明确定义,领域模型分实体 值对象和服务三种。

2012-12-22 18:31 "@banq"的内容
CQRS是为了更好将DDD与现有技术架构结合而推出的一种分离架构。领域专家强调领域模型要充血,不能被技术架构绑架,我们当然应该首先满足,但是数据库成熟强大的查询能力我们也不能走极端弃之不用,因为我们的系统不但要满足领域专家,而且还有用户要求 ...

有道理,CQRS之所以分离是为了让command和query分别发挥他们的作用,既能满足领导专家的需要,也能满足用户复杂的查询需要,于是command和query进行了分离,不错的设计,有了CQRS应该更能利于OO思想和DDD思想的推广
另外,有一个概念:EventSourcing是什么概念?是我们一直谈的异步事件用于同步状态到Query吗?

2012-12-22 18:36 "@banq"的内容
我没有看Axon这个例子,但是按照DDD来理解,一个聚合根实际就是一个实体,就像一个局长实际也是一个人而已,聚合根只不过是其担任聚合之首的职责。

如果Axon将这两者分离,要么你理解有误,要么它只是一种CQRS框架,而不是严格意义上的 ...


我的理解实体对应DB的一张表,实体都是DB的字段映射,还有set,get,没有别的,就像EJB的实体Bean,Hibernate的entity类一样,值对象就是VO类或DTO,就像CQRS中的Command,Struts的FormBean一样,而服务则一般以Service结尾,比如UserService, LoginService,MatchService等,是用来实现业务逻辑的,在Axon中,领域模型继承了AbstractAnnotatedAggregateRoot类,有一些方法,比如changeName(), delete(), handleEvent(Event)等,而实体就对应DB表,并用@Entity修饰,在属性上也有@NotNull,@Size等,不知道我说的实体和你说的实体是不是一个东西?
[该贴被cloudstack于2012-12-22 19:40修改过]

2012-12-22 19:32 "@cloudstack"的内容
而实体就对应DB表,并用@Entity修饰,在属性上也有@NotNull,@Size等,不知道我说的实体和你说的实体是不是一个东西? ...

如果你这样理解没有错的话,那么我可以百分之百肯定,Axon不是基于DDD的CQRS,因为在DDD中实体是一种领域模型,实体担任聚合根,你可以找本DDD书籍来看,你说的实体是我们批评的数据实体,失血实体,这是不应该出现的DDD系统中的,这种实体在JavaEE的EJB/JPA和Spring+Hibernate中到处都是。

DDD理论创始人Eric vans在这篇文章:2012年Eric Evans关于技术如何影响DDD的会话说:
对象概念其实很长时间已经被J2EE等重量框架摧残了很长时间,而且更被阴险的映射到关系数据库上。

怪不得你第一篇文章提CQRS,然后还没搞懂CQRS和DAO区别,原来被Axon这样的不纯正框架给误导了。呵呵。

[该贴被banq于2012-12-23 09:49修改过]

2012-12-23 09:48 "@banq"的内容
如果你这样理解没有错的话,那么我可以百分之百肯定,Axon不是基于DDD的CQRS,因为在DDD中实体是一种领域模型,实体担任聚合根,你可以找本DDD书籍来看,你说的实体是我们批评的数据实体,失血实体,这是不应该出现的DDD系统中的,这种实 ...

Axon的官网上我找了,没有发现DDD的字样,不清楚是不是基于DDD的,可能我理解错了,你说的实体就是Axon中的领导对象,继承了AggregateRoot的类,而与DataEntity没有关系,我以为实体就是指DataEntity。实体、值对象,服务的关系应该是实体是具有行为和状态的对象,实体通过服务实现业务操作,而整个过程中需要的数据,比如读取某个表中的数据,可以使用值对象,其实DataEntity也是一种值对象,比如Person是实体,Order是DataEntity,订单的表单提交时产生的叫值对象,Person对货物的业务操作用服务实现,而Person可以有apply(productId), pay(orderId), cancel(orderId)等行为
[该贴被cloudstack于2012-12-23 10:38修改过]

2012-12-23 10:33 "@cloudstack"的内容
其实DataEntity也是一种值对象 ...

这个我表示怀疑,因为过往都是流行使用set来设置值的,但值对象不允许set存在,它的创建方式是唯一的——构造函数,而且不能用Null作为参数。

好久没来这里了,也推广一下我的EventSourcing框架,不过是用c写的哦。https://github.com/tangxuehua/eventsourcing

其实一切的目的都是为了更好的做到让对象拥有它该有的职责,不能总是觉得逻辑只能用服务去实现。用banq的话来说就是一切都是为了让各个对象看起来正自然。该是谁的责任就应该是谁的责任。

只要明白这一点就行了,用什么框架,DDD,CQRS,Event Sourcing,DCI,etc. 从OO的角度来说,都是为了上面的目的。

就我目前的理解,OO设计与编程,最主要要把握的就是以下三点:
1)掌握如何分析对象该有的职责和固有属性;
2)掌握对象之间的关系;
3)掌握如何区分哪些信息是对象固有的属性,哪些信息是对象交互之后产生的,这些信息如何设计,是设计为新对象还是附属于已经存在对象之上;
理清楚上面三点,那OO设计与实现就很容易了。

所以,我觉得与其大家在这里大量谈论想法,理论。是否可以考虑基于实例的方式来讨论OO对象建模的合理性?这样是否可以更加快速的让人理解为什么DDD是有好处的?
[该贴被tangxuehua于2013-01-01 22:25修改过]

mark

很精彩的讨论,对于一个刚刚接触DDD和CQRS的人来说,对DDD的概念和DDD如何在技术架构上落地有了清晰的认识。记得以前在用Spring、Hibernate进行OO编程的时候,就觉得与所谓的OO编程思想有很大出入,为此社区还“发明”了贫血模型这样怪异的“专业术语”,当时就怀疑可能是因为现有的实现技术导致无法实现真正意义的OO设计。

至于现有的CQRS等技术架构是否可以从根本上解决技术实现与领域模型之间的匹配问题,只能拭目以待了。

不过目前流行的支持DDD和CQRS开发的框架似乎还不是很多,不知道目前DDD和CQRS目前的发展如何?另外LMAX和DDD、CQRS有什么关系么?
[该贴被erik200xx于2013-08-14 16:22修改过]