说明:
我有以下结构:
Item
对象包含Group(s)
数组,每个组包含User(s)
数组。
Item
具有以下API:
addUser
,removeUser
,addGroup
,removeGroup
,addUnit
和removeUnit
。
每个操作都会触发每个用户rank
属性的新计算(针对特定组)。
我正在寻找一种方法,在每个API的操作结束时,方法calcRank
将被触发,而不会显式调用它(类似于OnExit装饰器)。
答案 0 :(得分:1)
The Advice Pattern在一种像JavaScript一样动态的语言中非常简单:
function before(behavior) {
return method => function beforeHandler(...args) {
behavior.apply(this, args);
return method.apply(this, args);
};
}
function after(behavior) {
return method => function afterHandler(...args) {
const result = method.apply(this, args);
behavior.apply(this, [args, result]);
return result;
};
}
const id = _ => _;
function withAdvice({before: beforeBehavior = id, after: afterBehavior = id, skip: [] }) {
return Class => Object.keys(Class.prototype).forEach(methodName => {
if (!skip.contains(methodName)) {
const method = Class.prototype[methodName];
const afterDecorator = after(afterBehavior);
const beforeDecorator = before(beforeBehavior);
Class.prototype[methodName] = afterDecorator(beforeDecorator(method));
}
});
}
@withAdvice({
after() {
this.calcRank();
},
skip: ['calcRank']
})
class Item {
addUser() {}
removeUser() {}
addGroup() {}
removeGroup() {}
addUnit() {}
removeUnit() {}
calcRank() {}
}