集群环境下DDD设计,怎样操作实体

13-06-20 axlfu
    

假设简单的场景,创建一个吃货,然后吃货在:吃饭吃饭吃饭……

假设是B/S结构

注册之后就产生了一个吃货的实体(实例)

点击吃饭按钮,就会发送吃饭请求

在设计的时候,ddd让我们从两方面考虑问题

1.能准确的描述领域模型

2.和实现相结合,不要死磕

我的问题就是

为了设计漂亮点儿,当然是不希望收到吃饭请求的时候,都先把实体从数据库查出来,这不符合对象行为嘛。

但在集群环境下,或许还真要先load实体出来,再让他执行吃饭的动作

我是应该不care这个“实现不符合对象行为”的问题呢?

还是需要注册后就把实体放在集群的内存中,让后面的操作都变成自然的对象行为,而不需要加载动作?(这有点ddd绑架技术选型的意思)

引申出另一个问题

我们暴露给应用层的接口,接口参数是实体的标识?还是实体本身呢?

或者要把实体/聚合根直接在B/S传来传去么?

因为,如果不是引用实体本身的话,总感觉不那么ddd,

但用实体的话,传来传去包括序列化简直是浪费资源影响性能呢

    

banq
2013-06-20 13:24

初看题目,以为是集群环境下的实体如何分布的问题,假设楼主也有这个疑问:

DDD在分布式环境下采取的是CQRS读写分离架构,对于写操作,可以采取内存数据网格之类高集群性质的多台服务器实现。

无论在数据网格集群还是单机情况下,我个人认为,代码里只要显式访问仓储获得吃货这个实体即可,在仓储那里由框架隐式完成加载:先查询内存是否存在,如没有从数据库读取。Jdon框架目前是这样做的。

暴露给应用层,我也有时想到这个问题,将读写区分情况下,读场景肯定是要直接暴露,这种暴露不是聚合根暴露,而是聚合根的DTO暴露,CQRS下读取的是DTO对象,而写场景如果要将写操作完成的聚合根实体反映到应用层,序列化影响不是很大,要知道以前EJB在集群环境下,经常序列化,只不过当时眼不见为净,序列化性能成为服务器后端性能主要指标,见这个帖子可挑选序列化性能好的框架:http://www.jdon.com/45396

axlfu
2013-06-20 14:19

如果程序做文档看的话,是不是类似下面这样?

client: controller.eat(boyId,foodId){

boyAppObject.eat(boyId,foodId);

}

appLayer: boyAppObject.eat(boyId,foodId){

boy = boyRepo.get(boyId);

food = foodRepo.get(foodId);

boy.eat(food);

}

domainLayer: boy.eat(food){

addEatenFood(food);

fireEatenFoodEvent(event);

}

我发现这个问题是因为我意识上的一个误区,把表现层和应用层也按领域模型的实现来要求了,其实他们不是一个层面的对象……

banq
2013-06-20 15:05

是这样,你的感悟有道理