aop_demo.html
<script src="Aspects.js"></script>
<script>
// Business logic
function makeGreeting(text) {
return "Hello " + text + "!";
}
alert(makeGreeting("world")); // Hello world!
</script>
<script>
// Advices
function aopizeAdvice(args) {
args[0] = "AOP " + args[0]; return args;
}
function shoutAdvice(result) {
return result.toUpperCase();
}
function ciaoAdvice() {
return "Bye-bye!";
}
</script>
<script>
// Weaver and fun
Aspects.addBefore(this, "makeGreeting", aopizeAdvice);
alert(makeGreeting("world")); // Hello AOP world!
Aspects.addAfter(this, "makeGreeting", shoutAdvice);
alert(makeGreeting("world")); // HELLO AOP WORLD!
Aspects.addAround(this, "makeGreeting", ciaoAdvice);
alert(makeGreeting("world")); // Bye-bye!
</script>
Aspects.js:
Aspects = new Object();
Aspects.addBefore = function(obj, fname, before) {
var oldFunc = obj[fname];
obj[fname] = function() {
return oldFunc.apply(this, before(arguments, oldFunc, this));
};
};
Aspects.addAfter = function(obj, fname, after) {
var oldFunc = obj[fname];
obj[fname] = function() {
return after(oldFunc.apply(this, arguments), arguments, oldFunc, this);
};
};
Aspects.addAround = function(obj, fname, around) {
var oldFunc = obj[fname];
obj[fname] = function() {
return around(arguments, oldFunc, this);
};
};
aop_demo.html
script src="Aspects.js"></script>
<script>
//Business logic
function Document(){}
Document.prototype = {
_id: 0,
_name: '',
name: function() {
return this._name;
},
id: function() {
return this._id;
},
save: function() {
return true;
},
open: function(id) {
this._id = id;
this._name = 'Ajax on AOP steroids'
return true;
}
}
function openDocument(id) {
var doc = new Document();
try {
doc.open(id);
} catch(e) {
alert(e);
return;
}
// Update icons and other user elements affected
alert("Doc id: " + doc.id());
return doc;
}
</script>
<script>
//Advices
function Lockable(){}
Lockable.prototype = {
_locked: false,
locked: function() {
return this._locked;
}
}
function lockOnOpen() {
// Lock this object
// If we didn't succeed
throw (new Error ("Failed locking " + this._name));
// The object is locked
this._locked = true;
var ret = proceed();
return ret;
}
</script>
<script>
// Weaver and fun
try {
Aspects.addIntroduction(Lockable, Document);
Aspects.addAround(lockOnOpen, Document, "open");
openDocument ( "test");
} catch(e) {
alert(e);
}
</script>
Aspects.js
InvalidAspect = new Error("Missing a valid aspect. Aspect is not a function.");
InvalidObject = new Error("Missing valid object or an array of valid objects.");
InvalidMethod = new Error("Missing valid method to apply aspect on.");
Aspects = new Object();
Aspects._addIntroduction = function(intro, obj) {
for (var m in intro.prototype) {
obj.prototype[m] = intro.prototype[m];
}
}
Aspects.addIntroduction = function(aspect, objs) {
var oType = typeof(objs);
if (typeof(aspect) != 'function') throw(InvalidAspect);
if (oType == 'function') {
this._addIntroduction(aspect, objs);
} else if (oType == 'object') {
for (var n = 0; n < objs.length; n++) {
this._addIntroduction(aspect, objs[n]);
}
} else {
throw InvalidObject;
}
}
Aspects.addBefore = function(aspect, obj, funcs) {
var fType = typeof(funcs);
if (typeof(aspect) != 'function') throw(InvalidAspect);
if (fType != 'object') funcs = Array(funcs);
for (var n = 0; n < funcs.length; n++) {
var fName = funcs[n];
var old = obj.prototype[fName];
if (!old) throw InvalidMethod;
obj.prototype[fName] = function() {
aspect.apply(this, arguments);
return old.apply(this, arguments);
}
}
}
Aspects.addAfter = function(aspect, obj, funcs) {
if (typeof(aspect) != 'function') throw InvalidAspect;
if (typeof(funcs) != 'object') funcs = Array(funcs);
for (var n = 0; n < funcs.length; n++) {
var fName = funcs[n];
var old = obj.prototype[fName]; if (!old) throw InvalidMethod;
obj.prototype[fName] = function() {
var args = old.apply(this, arguments);
return ret = aspect.apply(this, Array(args, null));
}
}
}
Aspects._getLogic = function(func) {
var oSrc = new String(func);
var nSrc = '';
var n = 0;
while (oSrcn) {
if (oSrc[n] == '\\n' || oSrc[n] == '\\r') nSrc[n++] += ' ';
else nSrc += oSrc[n++];
}
n = 0;
while (nSrc[n++] != '{');
nSrc = nSrc.substring(n, nSrc.length - 1);
return nSrc;
}
Aspects.addAround = function(aspect, obj, funcs) {
if (typeof(aspect) != 'function') throw InvalidAspect;
if (typeof(funcs) != 'object') funcs = Array(funcs);
var aSrc = this._getLogic(aspect);
for (var n = 0; n < funcs.length; n++) {
var fName = funcs[n];
if (!obj.prototype[fName]) throw InvalidMethod;
var oSrc = 'var original = ' + obj.prototype[fName];
var fSrc = oSrc + aSrc.replace('proceed();','original.apply(this, arguments);');
obj.prototype[fName] = Function(fSrc);
}
return true;
}
posted on 2005-12-22 12:39
老妖 阅读(825)
评论(0) 编辑 收藏