06.Javascript设计模式之桥接模式----Bridge
本文主要通过例子的形式来介绍设计模式中的桥接模式。
在设计一个Javascript API的时候,可以用这个模式来弱化它与使用它的类和对象之间的耦合。按照GoF的定义,桥接模式的作用在于“将抽象与其实现隔离开来,以便二者独立变化”。 这种模式对于Javascript中常见的事件驱动编程非常有用。
桥接模式示例一:DOM事件监听器
假使有这样一个命题:页面上有多个按钮,还有一张可控尺寸的图片,id为img,要求点击不同的按钮(根据按钮的value判断,如:value="600x800"),图片的尺寸得到相应的改变。 于是,完成这个操作,通常情况下,我们不考虑设计模式,这样做就能完成功能:
addEvent(domElement,"click",function(e){ var btnValue = this.value.split("x"); var size = { width : btnValue[0], height : btnValue[1] }; var oImg = document.getElementById("img"); oImg.style.width = size.width + "px"; oImg.style.height = size.height + "px"; });
这样的设计,完全能实现我们的功能,点击不同的按钮,图片的大小都会随之而变化。
但是,如果你要对这个功能进行单元测试,或者甚至你想在像Firebug那样的命令行的环境中来调试并运行它,那就表现的有些困难了。
因此,在这个时候我们考虑到了使用桥接模式,将监听器方法抽取出来,成为一个单独的API函数,而且保证该API函数与节点本身没有必然的耦合,我们的设计如下:
var changeSize = function(buttonValue){ var btnValue = buttonValue.split("x"); var size = { width : btnValue[0], height : btnValue[1] }; var oImg = document.getElementById("img"); oImg.style.width = size.width + "px"; oImg.style.height = size.height + "px"; }; var changeSizeBridge = function(e){ changeSize(this.value); }; addEvent(domElement,"click",changeSizeBridge);
通过这样的设计,功能也能得到非常完美的实现,并且,这个API的使用范围也大大拓宽了,提供给了我们更大的设计自由。 非常明显地可以看出,这个时候的changeSize方法并没有和事件对象绑定在一起,我们可以在单元测试中单独的运行这个API,也可以在独立的命令行模式下 快速调试我们设计的这个代码,我们可以这样来单独测试:
changeSize("1204x768");//将图片的大小改为1024*768
桥接模式最常见和实际的应用场合之一就是事件监听器回调函数。
桥接模式示例二:特权函数
除了在事件回调函数与接口之间进行桥接外,桥接模式也可以用于连接公开的API代码和私用的实现代码。此外,它还可以用来把多个类连接在一起。从类的角度来看, 这意味着把接口作为公开的代码编写,而把类的实现作为私用代码编写。
如果一个公用的接口抽象了一些也许应该属于私用性的较为复杂的任务,那么可以使用桥接模式来收集某些私用性的信息。可以用一些具有特殊权利的方法作为 桥梁以便方位私用变量空间,而不必冒险下到具体实现的浑水中。这个特例中的桥接性函数也称之为特权函数。
下面举一个简单的例子,通过实例设置并获取其私有的属性:
var Human = function(){ //这里定义人类的脚的数量,这个是人类的固有特征,不可改变 var footNum = 2; //通过这个方法,即可获取人类脚的数量 this.getFootNum = function(){ return footNum; }; }; var zhaoxianlie = new Human(); alert(zhaoxianlie.getFootNum()); //这里就会告诉大家,赵先烈有两只脚
当然了,桥接模式的例子非常非常的多,只要想的倒,大多都可以模拟。
本文参考《Javascript设计模式》【Ross Harmes,Dustin Diaz】
小生愚昧,文中如有阐述之不当,还请不要介怀