我正在考虑一种通用机制来跟踪对象的任何成员的更改。这个想法基本上是在调用 set
时将时间戳保存到某个成员 lastModified
中。
到目前为止我的想法是有一些父类(这里是伪代码)
class Tracker {
time lastModified;
void onChildSet() {
lastModified = NOW();
}
}
并为我的特定对象继承它
public class Object extends Tracker {
sometype member;
void setMember(sometype value) {
member = value;
onChildSet();
}
}
我不喜欢这种方法的是,我不知道如何避免从父类显式调用 onChildSet()
的必要性。实际上,我正在寻找某种方法来自动更新 lastModified
而无需编写任何代码。有一些概念如何实现这一点吗?
最佳答案
大多数动态语言都有某种拦截方法调用的方法。例如,所有 ruby 对象都有一个方法“method_missing”,每当在 undefined object 上调用方法时都会调用该方法。您可以使用此功能设置代理对象来跟踪 LastModified 值。另一种动态语言,Actionscript 3.0 有 Proxy API 中的类。同样,您可以使用此代理类来拦截函数调用。不幸的是,使用这样的代理意味着您必须修改定义方法的方式。在 ruby 的情况下,method_missing 显然仅在该方法不存在时才被调用。这意味着您必须在对象上定义方法,然后由代理类包装该对象。看看我在 AS3 中整理的示例。对于要跟踪的属性,必须通过 trackSet 方法来定义,我们不能直接在 MyObject 类上定义该方法。 trackSet 存储对象中的属性名称以及回调函数。当在代理类上调用 setProperty 时,将根据 setters 对象检查属性名称,如果存在,则更新该属性的 LastModified 并调用该属性回调。
package {
import flash.utils.Proxy;
import flash.utils.flash_proxy;
public dynamic class Tracker extends Proxy {
private var setters : Object;
public function Tracker() {
setters = { };
}
public function getLastModified(name : String) : Number {
return setters[name] ? setters[name].lastModified : 0;
}
protected function trackSet(name : String, fn : Function) : void {
setters[name] = {
lastModified: 0,
setter: fn
};
}
override flash_proxy function setProperty(name : *, value : *) : void {
if(!setters[name]) return;
setters[name].lastModified = new Date().time;
setters[name].setter(value);
}
}
}
-
package {
public dynamic class MyObject extends Tracker {
public function MyObject() {
trackSet('member', setMember);
}
private function setMember(val : String) : void {
trace('set member =', val);
}
}
}
-
var obj : MyObject = new MyObject();
obj.member = 'monkey';
trace('member getlast modified at', obj.getLastModified('member'));
关于oop - 跟踪对象的修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11873045/