`
touchmm
  • 浏览: 1004284 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

JavaScript中IOC【Inversion of Control】模式和AOP模式、观察者模式的交融

阅读更多

注:本文中部分描述都是操作我的书《JavaScript高级应用与实践》而言,还请朋友们多多支持我的书,详情请见:

博主网站地址:

http://m9m.3322.org/doc/js/md00.jsp

“北京电子工业出版社”地址

http://www.phei.com.cn/bookshop/bookinfo.asp?bookcode=TP061230%20&booktype=main

这里讲的IOC模式是指,一种很容易切入已有对象或类的模式,使得你的设计能很好的监视、改变现有设计的运行过程、结果。
注意:再次重申一下,JS中的对象和类的概念非常模糊,类也是一种对象,不过它区别于对象的特征是,可以直接使用new运算符号来
产生多个不同的、互不干扰的对象实例,而对象要产生多个互不干扰的对象实例,只能通过深度克隆。
// 有的人说JAVA的IOC是通过工厂类来实现,也就是同样的方法传入不同的类名获取到不同的对象实例,其实不然。
低侵入性似乎也成了判定一个框架的实现技术好坏的标准之一,而IOC则是通过依赖注入来实现其"好莱坞原则"
【不要给我们打电话,我们会给你打电话(don't call us, we'll call you)。可以理解为:被动调用原则】。

AOP【Aspect Oriented Programming】模式
面向方法编程,可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。
是OOP模式的延续,是Aspect Oriented Programming的缩写,意思是面向方面编程。AOP实际也是GoF设计模式的延续,
设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。
Java的AOP的实现方式之一是实现接口IntroductionInterceptor、MethodInterceptor来实现动态代理的。

// o 是需要IOC控制的对象,或类【类的时候只能对原型进行IOC】
// func 你编写的Filter方法,也叫IOC控制函数
// arD 一般调用的时候用null,函数内部使用
// bPrototype为真表示只对其原型进行处理
var IOCReflect = function(o, func, bFlg, arD, bPrototype)
{
// 防止递归循环引用
arD || (arD = {"self": o});
if(bPrototype)
{
if(!!o["prototype"])
return;
o = o["prototype"];
}

for(var k in o)
{
if("function" === typeof o[k])
{
// 利用匿名函数保护_fnc的有效性直到o[k] = function()的无效为止。
// 不能在o[k] = function()里面直接用o[k]的原因是因为k接着下轮循环就变化了
(function()
{
var p = k, _fnc = o[p];
o[k] = function()
{
var a = [];
a = Array.apply(a, arguments);
// 对过滤函传入的参数是:函数名、被过滤的函数对象、被过滤的函数对象执行的参数
if(func.apply(o, [p, _fnc, a]))
_fnc.apply(o, a);
a = null;
};
})();
}
else if(bFlg && null !== o[k] && "object" === typeof o[k])
{
if(arD["self"] !== o[k] && !arD[k])
arD[k] = o[k], IOCReflect(o[k], func, !!bFlg, arD);
}
}
};

var myClass = {
name: "xiatian",
dsp: function()
{
var a = [];
a = Array.apply(a, arguments);
a.push(this.name);
alert(a.join("\n"))
},
other: {
name: "summer",
display: function()
{
var a = [];
a = Array.apply(a, arguments);
a.push(this.name);
alert(a.join("\n"))
}
}
};

IOCReflect(myClass, function()
{
// 参数获取
var a = [];
a = Array.apply(a, arguments);
alert(["监控中的方法名:" + a[0], "\n监控中的参数(这里还可以改变参数的内容):\n" + a[2].join("\n")].join("\n"));
a[2][1] = "夏天";
return true;
}, true);

// 测试一下递归引用
myClass["myobj"] = myClass;

// 执行看看
myClass.dsp("你的名字:", "顶级配置系统!?");
myClass.other.display("我的名字:", "你猜猜看,谁说了算?");

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics