Created
July 8, 2011 09:00
-
-
Save fundon/1071396 to your computer and use it in GitHub Desktop.
JavaScript, Aspect Oriented Programming(AOP)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function AOP(obj, advice) { | |
this._instance = obj; | |
this._advice = advice; | |
} | |
AOP.prototype = { | |
_method: null, | |
_params: null, | |
result: null, | |
setAdviceResult: function(result) { | |
this.result = result; | |
}, | |
getAdviceResult: function() { | |
return this.result; | |
}, | |
proceed: function() { | |
if (this._instance instanceof AOP) { | |
this._instance.setAdviceResult(this.getAdviceResult()); | |
} | |
//console.log(this._params); | |
return this._instance[this._method].apply(this._instance, this._params); | |
} | |
}; | |
AOP.getInstance = function(target, advice) { | |
var _class = target['class'], _method = target['method']; | |
var obj = new _class(); | |
var method = obj[_method]; | |
var depth = 0; | |
do { | |
obj = new AOP(obj, advice); | |
obj[_method] = function() { | |
return function() { | |
this._params = arguments; | |
try { | |
try { | |
var ret = this._advice.aroundAdvice(this); | |
return ret; | |
} catch (e) { | |
this._advice.beforeAdvice(); | |
var ret = this.proceed(); | |
this._advice.afterAdvice(); | |
return ret; | |
} | |
} catch (e) { | |
return this._advice.throwsAdvice(e); | |
} | |
} | |
}(); | |
obj._method = _method; | |
obj.depth = depth++; | |
//console.log(obj.depth + '-' + advice.name); | |
} while (advice = advice.getPreAdvice()); | |
return obj; | |
} | |
function Advice(advice) { | |
if (advice) { | |
this._pre_advice = advice; | |
} | |
} | |
Advice.prototype = { | |
_pre_advice: null, | |
getPreAdvice: function() { | |
return this._pre_advice; | |
}, | |
beforeAdvice: function() {}, | |
afterAdvice: function() {}, | |
aroundAdvice: function(aop) { | |
throw new Error(); | |
}, | |
throwsAdvice: function(error) { | |
return error; | |
} | |
}; | |
function LogAdvice() { | |
Advice.call(this, arguments[0]); | |
this.name = 'Log Advice'; | |
//console.log(this.name); | |
} | |
LogAdvice.prototype.__proto__ = Advice.prototype; | |
LogAdvice.prototype.aroundAdvice = function(aop) { | |
console.log('Log Around Advice before'); | |
var ret = aop.proceed(); | |
console.log('Log Around Advice after'); | |
return ret; | |
} | |
function CacheAdvice() { | |
Advice.call(this, arguments[0]); | |
this.name = 'Cache Advice'; | |
//console.log(this.name); | |
} | |
CacheAdvice.prototype.__proto__ = Advice.prototype; | |
CacheAdvice.prototype.aroundAdvice = function(aop) { | |
console.log('Cache Around Advice before'); | |
var ret = aop.proceed(); | |
console.log('Cache Around Advice after'); | |
return ret; | |
} | |
function PermissionAdvice() { | |
Advice.call(this, arguments[0]); | |
this.name = 'Permission Advice'; | |
//console.log(this.name); | |
} | |
PermissionAdvice.prototype.__proto__ = Advice.prototype; | |
PermissionAdvice.prototype.aroundAdvice = function(aop) { | |
//console.log('Permission Around Advice before'); | |
//var ret = aop.proceed(); | |
//console.log('Permission Around Advice after'); | |
//return ret; | |
throw new Error('Permission fail'); | |
} | |
PermissionAdvice.prototype.beforeAdvice = function() { | |
console.log('Permission Before Advice'); | |
} | |
function User() { | |
this.name = 'User Class'; | |
} | |
User.prototype.foobar = function() { | |
console.log('Hello foobar'); | |
return 'User.foobar'; | |
} | |
User.prototype.login = function() { | |
console.log('I did it'); | |
} | |
var user = AOP.getInstance({'class': User, 'method': 'foobar'}, new CacheAdvice(new LogAdvice(new PermissionAdvice()))); | |
user.foobar(1,2,34); | |
//var user = AOP.getInstance({'class': User, 'method': 'login'}, new CacheAdvice(new PermissionAdvice())); | |
//user.login(); | |
//console.dir(user); | |
//console.log(user instanceof AOP); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function AOP(obj, advice) { | |
this._instance = obj; | |
this._advice = advice; | |
} | |
AOP.prototype = { | |
_method: null, | |
_params: null, | |
result: null, | |
setAdviceResult: function(result) { | |
this.result = result; | |
}, | |
getAdviceResult: function() { | |
return this.result; | |
}, | |
proceed: function() { | |
if (this._instance instanceof AOP) { | |
this._instance.setAdviceResult(this.getAdviceResult()); | |
} | |
//console.log(this._params); | |
return this._instance[this._method].apply(this._instance, this._params); | |
} | |
}; | |
AOP.getInstance = function(target, advice) { | |
var _class = target['class'], _method = target['method']; | |
var obj = new _class(); | |
var method = obj[_method]; | |
var __method = _method.toLowerCase(); | |
var depth = 0; | |
do { | |
obj = new AOP(obj, advice); | |
obj[_method] = function() { | |
return function() { | |
this._params = arguments; | |
try { | |
try { | |
//var ret = this._advice.aroundAdvice(this); | |
var ret = (this._advice['around_' + __method] || function(aop){return aop.proceed();})(this); | |
return ret; | |
} catch (e) { | |
//this._advice.beforeAdvice(); | |
//var ret = this.proceed(); | |
//this._advice.afterAdvice(); | |
(this._advice['before_' + __method] || function(){})(); | |
var ret = this.proceed(); | |
(this._advice['after_' + __method] || function(){})(); | |
return ret; | |
} | |
} catch (e) { | |
return this._advice.throwsAdvice(e); | |
} | |
} | |
}(); | |
obj._method = _method; | |
obj.depth = depth++; | |
//console.log(obj.depth + '-' + advice.name); | |
} while (advice = advice.getPreAdvice()); | |
return obj; | |
} | |
function Advice(advice) { | |
if (advice) { | |
this._pre_advice = advice; | |
} | |
} | |
Advice.prototype = { | |
_pre_advice: null, | |
getPreAdvice: function() { | |
return this._pre_advice; | |
}, | |
beforeAdvice: function() {}, | |
afterAdvice: function() {}, | |
aroundAdvice: function(aop) { | |
throw new Error(); | |
}, | |
throwsAdvice: function(error) { | |
return error; | |
} | |
}; | |
function LogAdvice() { | |
Advice.call(this, arguments[0]); | |
this.name = 'Log Advice'; | |
//console.log(this.name); | |
} | |
LogAdvice.prototype.__proto__ = Advice.prototype; | |
LogAdvice.prototype.aroundAdvice = function(aop) { | |
console.log('Log Around Advice before'); | |
var ret = aop.proceed(); | |
console.log('Log Around Advice after'); | |
return ret; | |
} | |
function CacheAdvice() { | |
Advice.call(this, arguments[0]); | |
this.name = 'Cache Advice'; | |
//console.log(this.name); | |
} | |
CacheAdvice.prototype.__proto__ = Advice.prototype; | |
CacheAdvice.prototype.aroundAdvice = function(aop) { | |
console.log('Cache Around Advice before'); | |
var ret = aop.proceed(); | |
console.log('Cache Around Advice after'); | |
return ret; | |
} | |
function PermissionAdvice() { | |
Advice.call(this, arguments[0]); | |
this.name = 'Permission Advice'; | |
//console.log(this.name); | |
} | |
PermissionAdvice.prototype.__proto__ = Advice.prototype; | |
PermissionAdvice.prototype.aroundAdvice = function(aop) { | |
//console.log('Permission Around Advice before'); | |
//var ret = aop.proceed(); | |
//console.log('Permission Around Advice after'); | |
//return ret; | |
throw new Error('Permission fail'); | |
} | |
PermissionAdvice.prototype.beforeAdvice = function() { | |
console.log('Permission Before Advice'); | |
} | |
PermissionAdvice.prototype.around_foobar = function() { | |
console.log('Permission around, foobar'); | |
throw new Error('Permission around fail'); | |
} | |
PermissionAdvice.prototype.before_foobar = function() { | |
console.log('Permission before, foobar'); | |
} | |
function User() { | |
this.name = 'User Class'; | |
} | |
User.prototype.foobar = function() { | |
console.log('Hello foobar'); | |
return 'User.foobar'; | |
} | |
User.prototype.login = function() { | |
console.log('I did it'); | |
} | |
var user = AOP.getInstance({'class': User, 'method': 'foobar'}, new CacheAdvice(new LogAdvice(new PermissionAdvice()))); | |
user.foobar(1,2,34); | |
var user = AOP.getInstance({'class': User, 'method': 'login'}, new CacheAdvice(new PermissionAdvice())); | |
user.login(); | |
//console.dir(user); | |
//console.log(user instanceof AOP); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment