?
?
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8" /> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <title>3桥接(bridge)模式</title> </head> <body> <div id='div1'>asdasf</div> <button id='myTime'>点击开始加载ajax</button> <script type="text/javascript"> /* * 桥梁模式可以用来弱化它与使用它的类和对象之间的耦合,就是将抽象与其实现隔离开来,以便二者独立变化; * 这种模式对于JavaScript中常见的时间驱动的编程有很大益处,桥梁模式最常见和实际的应用场合之一是时间监听器回调函数。先分析一个不好的示例: */ var element = document.getElementById('div1'); element.onclick = function(){ new setLogFunc(); } /* * 为什么说这个示例不好,因为从这段代码中无法看出那个LogFunc方法要显示在什么地方,它有什么可配置的选项以及应该怎么去修改它。 * 换一种说法就是,桥梁模式的要诀就是让接口“可桥梁”,实际上也就是可配置。把页面中一个个功能都想象成模块,接口可以使得模块之间的耦合降低。 * 掌握桥梁模式的正确使用收益的不只是你,还有那些负责维护你代码的人。把抽象于其实现隔离开,可独立地管理软件的各个部分,bug也因此更容易查找。 * 桥梁模式目的就是让API更加健壮,提高组件的模块化程度,促成更简洁的实现,并提高抽象的灵活性。一个好的示例: */ element.onclick = function(){ //API可控制性提高了,使得这个API更加健壮 new someFunction(element,param,callback); } /* * 注:桥梁模式还可以用于连接公开的API代码和私有的实现代码,还可以把多个类连接在一起。 * 在文章封装介绍的部分提到过特权方法,也是桥梁模式的一种特例。《JS设计模式》上找的示例,加深大家对这个模式的理解: * 1 //错误的方式 2 //这个API根据事件监听器回调函数的工作机制,事件对象被作为参数传递给这个函数。本例中并没有使用这个参数,而只是从this对象获取ID。 3 addEvent(element,'click',getBeerById); 4 function getBeerById(e){ 5 var id = this.id; 6 asyncRequest('GET','beer.url?id=' + id,function(resp){ 7 //Callback response 8 console.log('Requested Beer: ' + resp.responseText); 9 }); 10 } */ //补全stz+: var XMLHttpFactory = function(){}; XMLHttpFactory.prototype = { createFactory:function(){ throw new Error('This is an abstract class'); } } var XHRHandler = function(){ XMLHttpFactory.call(this); } XHRHandler.prototype = new XMLHttpFactory(); XHRHandler.prototype.constructor = XHRHandler; XHRHandler.prototype.createFactory = function(){ var XMLHttp = null; if (window.XMLHttpRequest){ XMLHttp = new XMLHttpRequest(); }else if (window.ActiveXObject){ XMLHttp = new ActiveXObject("Microsoft.XMLHTTP"); } return XMLHttp; } XHRHandler.prototype.successful = function(req){ if(req.readystate==4){//请求状态为4表示成功 if(req.status == 200)//http状态200表示OK { alert("返回成功: "+req.statusText); Dispaly(); handle(req); //所有状态成功,执行此函数,显示数据 } else //http返回状态失败 { alert("服务端返回状态" + req.statusText); } } else //请求状态还没有成功,页面等待 { document.getElementById("myTime").innerHTML ="数据加载中"; } } var asyncRequest = function(method, url, callback) { var insXHRHandler = new XHRHandler(); var req = new XMLHttpRequest(); //insXHRHandler.createFactory(); req.open(method, url+ '&_dc=' + new Date().getTime(), true); // + '&_dc=' + new Date().getTime():去ajax缓存 req.onreadystatechange = function(){ if(req.readyState==4){//请求状态为4表示成功 // 居然错在 readyState。 s是大写!!!!!!!! if(req.status == 200)//http状态200表示OK { //alert("返回成功: "+req.statusText); Dispaly(req); callback(req.responseText); console.log("返回成功: "+req.responseText); console.log("eval(req.responseText).responseText1: "+ eval(req.responseText).responseText1); //所有状态成功,执行此函数,显示数据 } else //http返回状态失败 { alert("服务端返回状态" + req.statusText); } } else //请求状态还没有成功,页面等待 { document.getElementById("myTime").innerHTML ="数据加载中"; } } req.send(null); //发送请求 } function Dispaly(req) //接受服务端返回的数据,对其进行显示 { document.getElementById("myTime").innerHTML = req.responseText; } var addEvent = function(el,method,handle,bubble){ if(el.addEvent){ el.addEvent('on'+method, handle); }else{ el.addEventListener(method, handle, !bubble?false:true); } } //好的方式 //从逻辑上分析,把id传给getBeerById函数式合情理的,且回应结果总是通过一个回调函数返回。这么理解,我们现在做的是针对接口而不是实现进行编程,用桥梁模式把抽象隔离开来。 // var xhr = new Ajax('response.js', 'GET', '', function(resp) { // document.getElementById('myTime').innerHTML = eval(resp).responseText1; //typeof(eval(resp)); // }); // xhr.callServer(); function getBeerById(id,callback){ asyncRequest('GET','http://localhost:8082/jsTest2/designMode/response.js?id=' + id,function(resp1){ console.log('resp1 in getBeerById: ' + resp1); callback(resp1); }); } addEvent(document.getElementById('myTime'),'click',getBeerByIdBridge); function getBeerByIdBridge(e){ getBeerById(this.id,function(beer){ console.log('Requested Beer: ' + beer); console.log('Requested Beer2: ' + eval(beer).responseText1); }); } /* * 自己总结: getBeerByIdBridge就是接口,通过这个接口作为桥梁,调用真正的实现:getBeerById * 且传入回调函数,这函数还有个特点:参数就是真正实现函数里的返回结果的一个封装resp.responseText * 不难看出 asyncRequest也是个真正的实现函数,这时getBeerById就是桥了。。。桥接。 * 为了补全上面的例子:补全stz+: */ // </script> </body> </html>?
?
?
?
response.js:
?
?
({responseText1:"测试1234adwf........."})?
参考:
http://download.csdn.net/detail/nanlinfeixue/4203989#comment
http://blog.csdn.net/andy_sue/article/details/6739068
http://blog.csdn.net/sunxing007/article/category/534077
?
?
计划修改:
ajax改成jsonp跨域的。