`

桥接(bridge)模式

阅读更多

 

 

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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics