<!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跨域的。