程序员 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,它可以发出 apply
和 listen
事件 , 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
高深。。
这是cqrs框架,名字是 domain。 actor是一种设计模式。
cqrs? 啥东西啊
你可以搜索一下 cqrs 或去我网站 http://forjs.org/column/l1kaoULfgx