程序员 2014-10-22 一天的奇妙之旅
发布于 10 年前 作者 leogiese 3254 次浏览 最后一次编辑是 8 年前 来自 分享

原文 http://forjs.org/book/xyfULqrrXg/section/x1llupItu8g

程序员 2014-10-22 一天的奇妙之旅

推荐:《精通Node.js开发》 《Angular.js视频详解》

早上起来现在,我一直思考Actor监听领域事件后,谁来触发?

假如actor自己直到自己监听什么,并知道触发自身那个方法,后来想想不是那么回事,还是应该EventBus知道才对。

actor无非是告诉我要监听xxx事件,如果有这个事件发生,就调用我xxx方法。

先开发个监听方法,用于监听领域事件,但如何实现,应该由于domain框架实现.


listen(eventName,handleName){
    this.emit('listen',{eventName:eventName,handleName:handleName});
}

eventName 表示监听那个领域事件 ,handleName 表示处理这个事件的方法名,这个方法是 actor自身的。

Actor继承了EventEmitter,它可以发出 applylisten 事件 , domain框架内部会监听每个actor对象,通过这些事件做相应处理。

接着是对when 方法的更改,让 set 方法变成 private , 通过参数 把 set函数 注入到 when 函数里,这样有利于封装。

/** the method subclass must extend , and don't call self
 *  @param event  domain event
 */
when(event,set) {
    if (event.name === "remove") {
        set("alive", false);
    }
}

Actor 测试

测试创建new方法

    it("#new", function () {
        var actor = new Actor({name:"leo",book:"xxx"});
        should.exist(actor.get("id"));
        actor.get("name").should.eql("leo");
        actor.get("book").should.eql("xxx");
        should.exist(actor.get("id"));
        actor.get("alive").should.eql(true);

        should.not.exist(actor.set);

    })

测试 #json时发现个bug,所以需要修改 json

    get json() {
        var data = JSON.parse(JSON.stringify(this[dataKye]));
        data.id = this.get("id");
        data.alive = this.get("alive");
        return data;
    }

测试 #json

    it("#json",function(){
        var data = actor.json;
        data.name.should.eql("leo");
        data.book.should.eql("xxx")
        should.exist(data.id);
        should.exist(data.alive);
    })

OK,通过了!

发现个bug,需要修改一下:

    loadEvents(events) {
        if (this[isLoadEvents]) return;
        var set = this.set.bind(this);
        events.forEach(event => {
            this.when(event,set);
        })
        this[isLoadEvents] = true;
    }

var set = this.set.bind(this); 让set的cxt是自身,传递给when方法。

下一步又回到纠结的 apply 方法上了,到底如何抉择,这需要一个头脑风暴 … 因为apply这块定不来,其他就无法继续测试了。

还有个灵感就是 Actor 可以作为一个独立的项目。另外在模块写法上,还应该遵循commonjs的写法,这样更靠谱。

最后我用下面的方式实现了 apply,caller也是一个Actor表示,是调用者。

    // publish domain event
    // is apply success , then emit apply event
    apply(name, data, caller) {
        if (this.get("alive")) {
            var event = new Event(name, {
                callerId:caller ? caller.get(id) : null,
                callerType:caller ? caller.constructor.name : null,
                aggregateId: this.get("id"),
                aggregateType: this.constructor.className,
                data: data
            });
            this.when(event,this[set].bind(this));
            this.uncommittedEvents.push(event);
            this.emit("apply",this);
        }
    }

下面要测试一下:

    it("#apply",function(){

        var caller = new Actor();

        actor.on("apply",function(){
            this.uncommittedEvents.length.should.eql(1);
            var event = this.uncommittedEvents[0];
            should.exist(event.id);
            should.exist(event.time);
            event.name.should.eql("change");
            var data = event.data;
            data.callerId.should.eql(caller.get("id"));
            data.callerType.should.eql("Actor");
            data.sourceId.should.eql(actor.get("id"))
            data.sourceType.should.eql("Actor");

        })

        actor.apply("change",{name:"brighthas"},caller);

    })

顺利通过! lucky

4 回复

这是cqrs框架,名字是 domain。 actor是一种设计模式。

cqrs? 啥东西啊

你可以搜索一下 cqrs 或去我网站 http://forjs.org/column/l1kaoULfgx

回到顶部