Web前端面向切面编程
2012-04-17 11:19 刘联东 阅读(718) 评论(0) 编辑 收藏 举报What?
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。[百度百科]
Why?
a. event-msg 解构 model/view
b. 监控一切,而不失优雅~
在分析web性能、分析用户行为时,我们常常去修改前端代码,比如在前端DOM元素上插入大量监听事件,修改已有的JS文件。这样操作虽然能够达到目的,但是为代码管理带来很多问题。如何在不影响现有代码的基础上优雅的达到前端监控的目的呢。我们知道在Java中会使用AspecJ去监控系统异常、用户访问日志,系统性能监控等工作。那么在前端是否可以这么做呢?答案是肯定的,而且要比AspectJ更简单可依赖。因为JS是动态脚本语言,而且可以方便地使用代理模式。无需AspectJ对源代码的重新编译过程。对前端开发人员、后端开发人员和用户都是透明的,我们只需要在合适的地方插入一个JS文件即可达到目的。为了吊足大家胃口,我还是把我能够想想到的作用写出来吧。
a . 动态选择监听对象、方法、类。使用灵活方便。
b. 可以应用到前端mvc模型,解构mvc三层结构。统一使用aop提供的事件消息调度各层方法。
c. 前端异常处理,与Java类似,对exception处理函数的监控,记录用户操作中产生的一场。这需要FE对前端Exception的良好定义。
d. 用户行为分析, 用户的操作行为表现为对象、函数、类的创建或者调用。对这些元素的监控能够在前端产生用户日志,降低用户行为采集的难度。采集的数据可以Ajax实时提交到Server中。
About?
现在还没有完整独立的JS AOP框架,但是在很多JS框架中已经用了类似的思想。比如dojo.js (有待研究), 如果有同学对AOP on js敢兴趣,希望能够一起研究。
以下是我的一个简单的AOP实现
http://liandong.sinaapp.com/poiser/aop/demo.html
_____________________________________inspector.js________________________________________
function inspect(owner ){
var _$ ={};
_$['before'] = function(action, handle){
_$[action].before = handle;
}
_$.after = function(action, handle){
_$[action].after = handle;
}
var cutpoint = function(item){
var attributes = [];
var cnt = 0;
var name = item;
var agend = function(str){
cnt ++;
//fire the before event
if(agend.before){
agend.before.call(this, {target:name,count:cnt,args:arguments});
}
//call the prim function
owner[item].apply(owner, arguments);
//update basic type attributes
for(var i=0; i<attributes.length; i++){ _$[item] = $[item];}
//fire the after event
if(agend.after){
agend.after.call(this,{target:name,count:cnt,args:arguments});
}
}
return agend;
}
// inject cutpoint for Object
for(var item in owner){
if(owner[item] instanceof Function){
_$[item] = new cutpoint(item);
}else if($[item] instanceof Object){
_$[item] = owner[item];
}else{
_$[item] = owner[item];
attributes.push[item];
//store the valriabl list for the basic type( Number , boolean )
}
}
return _$;
}
/*
$ = inspector($);
$.before('action',handle);
$.after('action',handle);
*/
__________________________________________________________
_______________demo.html____________________________________________
<html>
<title>Aspect oriented programming</title>
<body>
<div id="tip_div" ></div>
<form>
<input type='text' onkeyup='window.user.input(this.value)'>
<input type='button' onclick='window.user.submit()' value='sumbit'>
</form>
</body>
<script src="inspector.js"></script>
<script>
function User(){
var len = 0;
var cnt = '';
this.input = function(content){
cnt = content;
// console.log("len = "+ len);//do something as you want
}
this.submit = function(){
alert(' content is '+ cnt);//do something as you want
}
}
var user = new User();
function inspect_user(){
var tip = document.getElementById('tip_div');
function inspect_event_log(str){
return function(cutEvent){
tip.innerText = tip.textContent =(str+" you've called ["+ cutEvent.target+"] for [" + cutEvent.count+"] times , the arg is ["+cutEvent.args[0])+"]";
}
}
function inspect_input(cutEvent){
var cnt = cutEvent.args[0];
if(cnt.length < 256 ){
tip.innerText = tip.textContent = "you can input ["+(256 - cnt.length)+"] words";
}else{
tip.innerText = tip.textContent = "pls keep your texts under 256 words";
}
}
//inspect on object
user = inspect(user);
user.after('input', inspect_input);
user.before('submit', inspect_event_log('[u will submit]'));
user.after('submit', inspect_event_log('[cons. we get your submit]'));
}
//if you dont need inspector, remove follow sentence.
inspect_user();
// inspect on class
// inspect for event_msg modles, such as mvc for front-end
// more works for next...
</script>
</html>