用Scala和Akka实现DDD

Implementing Domain-Driven Design一书的作者vaughn vernon最近在研究用scala和akka来实现DDD,如果有同好,可以一齐关注、学习。
https://vaughnvernon.co/?p=770

他又写了一篇revisited,好像是将Actor中状态还是引用共享出去了,这违反聚合根不能暴露内部引用原则,也违背Actor模型的share nothing原则,作为专门出DDD书的知名作者,如果真是出这种错误,让人惊愕。

看其代码,使用Actor作为一个缓存容器,里面再装聚合,这个思路比较奇怪,Actor应该直接实现聚合,然后再将Actor至于缓存之中。

当然比这篇文章:http://www.jdon.com/38315使用Actor来实现仓储要高明一些:


trait AccountRepository extends Actor
class RedisAccountRepository extends AccountRepository


这里有详细的讨论,说到actor引用共享的问题。

我大概看了一下他们讨论,楼主想用Akka的actor实现如下过程:
1.Some command comes in to modify a given Aggregate Root (AR) entity, 命令进来修改聚合根实体

2.If an Actor representing the AR is not already running in the system, create it _atomically_ (i.e. make sure you never have more than one Actor representing a specific entity)
如果一个聚合根实体Actor不存在内存中,那么自动创建( 从仓储中,并且保证只能有一个)

3.Actors should be removed after a period of idleness. This will avoid keeping actors around for entities with low interaction rates, but ensure 'hot' entities are kept in memory for performance (starting a new actor requires loading events from an event store in order to restore the memory image representing the entity state)
(这个Actor过段时间闲置应该移除,让最热的聚合根留在内存中)

呵呵,Jdon框架就是通过引入in-memory cache这么干的。

使用Actor作为聚合根实体,还需要一些预先处理过程,比如actor的start和stop,只能使用两个Actor嵌套来,父Actor作为容器管理者。

晕倒,只能说Actor不是为了聚合根诞生的啊。显然Akka框架发明者虽然和DDD的Evans想到一块儿去了,但是两者没有衔接好。

相反,使用Jdon框架,用元注解@Model 就能够让任何POJO成为聚合根,无任何预先处理,无需调用start或stop。嘿嘿。



[该贴被banq于2013-10-30 17:21修改过]

akka的妙处就在多层监管,根据需要实现相应的Strategy,做到真正的resilient。目前akka是实现reactive 宣言最好的,实现DDD只是副作用。

Akka的Actor的supervision比较神奇,灵活性强。而RxJava则在语法上要酷一些。

Akka的coordinated事务不错,比如两个账户之间转账,在DDD实现中使用EventSourcing,在两个账户之间通过事件协调,coordinated能让这个"你扣100,我加100"变成原子性操作。

[该贴被banq于2013-10-31 11:23修改过]

不可能做到这点吧。