通常,在胖客户端B/S从程序中,前端JavaScript脚本是最难维护的,由于客户端运行环境的多样性和脚本对运行属主的依赖型,开发人员常常无法将用户的错误在本机上重现.于是,当大量JavaScript存在的时候,对系统运行状态(包括日志和性能)的监视显得特别重要.当某个客户端出错或宕机时,就可以要求用户将系统运行历史和当前信息发送给开发人员进行分析.
然而,当日志过多的侵入业务逻辑代码,则可能将代码的稳定性和可读性产生负面影响.下面的程序可以在不修改程序代码的情况下扩展一段程序的功能,以此很方便地对调用的堆栈和过程进行监视.
/**
*
*AOPSupport 1.0
*Written by JarezWu
*Last Updated on 2007-3-9
*
*/
AOPSupport={
/**
* JavaScript方法代理,包装一个方法
* fn:方法名称
* obj:方法拥有者
* roundFunc:包装方法
*/
round:function(fn/*String*/,obj/*Object*/,roundFunc/*Function*/){
var preserved=["alert"];
for(var i=0,len=preserved.length;i<len;i++){
if(preserved[i]==fn){
throw new Error("无法监视"+fn);
}
}
if(!obj){//默认的Context为Global
obj=self;
}
var of=obj[fn];
if(!of){
return;
}
var nf=function(){
var args=arguments;
var invocation=new function(){
this.args=args;
this.method=of;
this.context=obj;
var self=this;
this.proceed=function(){
return self.method.apply(self.context,self.args);
}
}
return roundFunc.call(obj,invocation);
}
obj[fn]=nf;
}
}
举例说明:
1.增加逻辑
function foo(){
alert("核心业务");
}
foo();
function bar(){
alert("增值服务");
}
AOPSupport.round("foo",null,function(invocation){
invocation.proceed();
bar();
});
foo();
2.记录日志
Logger={//一个日志记录器
trace:function(info){
//log stack trace
},
error:function(info){
//log error
},
debug:function(info){
//log output
},
dump:function(){
//output logged info
}
};
var obj=new Object();//示例对象
obj.doIt=function(){//示例方法
//do something
}
obj.doIt();
//下面包装程序的运行过程
AOPSupport.round("doIt",obj,function(invocation){
Logger.trace("start:"+invocation.method);//跟踪开始
try{
Logger.debug(invocation.args);//记录参数
var result=invocation.proceed();//调用
Logger.debug(result);//记录结果
}catch(e){
Logger.error(e);//记录异常
}
Logger.trace("end:"+invocation.method);//结束跟踪
});
obj.doIt();//运行
Logger.dump();//打印跟踪信息