DDD思考之三 谁负责把Entity放入Repository?

Qiluluwawa 2011-03-21

这个问题在贫血模型里是不存在的,反正domain model都是被扒光的数据容器,无论给主键赋值还是通过DTO存取都是Service的事情。在充血模型中,这些又该是谁的责任呢?

首先考虑ID,ID分两种:用户在client填写的(比如UserId)以及系统自动生成的(比如单号),后者一般在Repostory中提供诸如getNextOrderNo()等方法。由另一个coordinator的角色来完成Entity的装配。

Id id=orderRepo.getNextOrderNo();
Order order=new order(id);

这样的好处是将Entity从获取ID的责任中解放出来,给测试带来方便。

至于这个coordinator有三种情况,Factory/(Domain)Service/(Application) Service都可以完成。

再看Repository.store(),这也不是Entity自己的责任,让对象把自己装入Repository就像让人抓住自己的头发拔离地球一样可笑。那么Factory是不是适合作这件事呢?一开始我是这么作的,但后来觉得这样不是很适合:Factory的作用只是生产出一个完整对象交给它的调用者,并不需要关心这个对象下面往何处去。就像现实世界中, 生产车间产出产品,却不知道其会被送到仓库还是质检车间。产品的流向应该由更高层的对象关心,比如(Domain)Service/(Application) Service 中的CreateXXX方法。

这样看来,Factory不负责对象持久化,它更集中在逻辑上(保持不变量)。Factory是和Domain结合很精密的部分,而Domain Service 和Application Service(中的CreateXXX)从持久化的角度看并无区别,都要负责持久化操作:Domain Service只是把App Service中公用的东西提升到了Domain中,相当于一个Facade模式,和Domain结合不是那么紧密。

既然不紧密,那么一个CreateXXX是放在Domain Service还是App Service中,就是比较随意的选择了。随着重构的进行,会有相当一部分CreateXXX显现出从App Service 提升到Domain Service中的需要,这就是比较考验判断的时候了。

相关推荐