zoukankan      html  css  js  c++  java
  • JavaScript设计模式(4)-桥接模式

    桥接模式

    在设计一个 Js API 时,可用来弱化它与使用它的类和对象之间的耦合

    1. 事件监听器的回调函数

    function getBeerById(id, callback) {
        asyncRequest('GET', 'beer.uri?id=' + id, function(res){
            callback(resp.responseText)
        })
    }
    
    function getBeerByIdBridge (e) {   // 桥接元素:事件监听器的回调函数
    
        // 避免把 this.id 耦合到函数 getBeerById 中
        getBeerById(this.id, function(beer) {
            console.log('Requested Beer: ' + beer)
        })
    }
    
    addEvent(element, 'click', getBeerByIdBridge);
    

    2. 桥接性函数:特权函数

    var Public = function() {
        var secret = 3;
        this.privilegedGetter = function() {
            return secret
        }
    }
    
    // usage
    var o = new Public;
    var data = o.privilegedGetter()
    

    3. 用桥接模式联结多个类

    var Class1 = function(a, b, c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
    var Class2 = function(d) {
        this.d = d;
    }
    
    var BridgeClass = function(a, b, c, d) {
        this.one = new Class1(a, b, c);
        this.two = new Class2(d)
    }
    

    4. 构建 XHR 连接队列

    // 获取 xhr 对象函数
    var asyncRequest = (function() {
        function handleReadyState(o, callback) {      // 其实也可以用 xhr.onreadystatechange 来实现而不用 setInterval 来监听 xhr 的 readyState
            var poll = window.setInterval(function(){
                if(o && o.readyState == 4) {
                    window.clearInterval(poll);
                    if(callback) {
                        callback(o)
                    }
                }
            }, 50);
        }
    
        var getXHR = function() {
            var http;
            try {
                http = new XMLHttpRequest;
                getXHR = function() {           // memoizing
                return new XMLHttpRequest;
                }
            }catch(e) {
                var msxml = [
                'MSXML2.XMLHTTP',
                'MSXML2.XMLHTTP.3.0',
                'Microsoft.XMLHTTP'
                ];
                for(var i=0, len = msxml.length; i<len; i++) {
                    try {
                        http = new ActiveXObject(msxml[i]);
                        getXHR = function() {
                            return new ActiveXObject(msxml[i]);
                        };
                        break
                    }catch(e) {
                        continue;
                    }
                }
            }
            return http;
        };
    
        return function(method, url, callback, postData) {
            var http = getXHR();
            http.open(method, url, true);
            handleReadyState(http, callback);
            http.send(postData || null);
            return http;
        }
    })()
    
    Function.prototype.method = function(name, fn) {
        this.prototype[name] = fn;
        return this
    }
    
    
    // 实现队列
    DED.Queue = function() {
        this.queue = [];
        this.retryCount = 3;
        this.currentRetry = 0;
        this.paused = false;
        this.timeout = 5000;
        this.conn = {};
        this.timer = {};
    }
    
    DED.Queue.method('flush', function(){
        if(!this.queue.length > 0) {   // 当队列长度等于 0 时进入 if
            return;
        }
        if(this.paused) {
            this.paused = false;
            return
        }
        var that = this;
        this.currentRetry++;
    
        // 如果在规定次数内,则继续重复请求,否则结束当前该请求
        var abort = function() {
            that.conn.abort();  // 终止该请求,readyState 属性将被置为 0
            if(that.currentRetry == that.retryCount) {
                // that.onFailure.fire();
                console.log('failure: ' + that.queue[0].url)
                that.currentRetry = 0;
            } else {
                that.flush();
            }
        }
    
        var callback = function (o) {
            document.getElementById('feed-readers').innerText = o.response
            console.log(o)
    
            // 停止超时处理程序
            window.clearTimeout(that.timer);
            that.currentRetry = 0;
    
            // 剔除当前请求成功的请求项
            that.queue.shift();
            // that.onFlush.fire(o.responseText);
            if(that.queue.length == 0) {
                // that.onComplete.fire();
                return;
            }
            // 继续新的请求
            that.flush()
        }
    
        this.conn = asyncRequest(
            this.queue[0]['method'],
            this.queue[0]['url'],
            callback,
            this.queue[0]['params']
        )
        this.timer = window.setTimeout(abort, this.timeout);
    
    }).method('setRetryCount', function(count) {
        this.retryCount = count;
    }).method('setTimeout', function(time) {
        this.timeout = time;
    }).method('add', function(o) {
        this.queue.push(o);
    }).method('pause', function() {
        this.paused = true;
    }).method('dequeue', function() {
        this.queue.pop()
    }).method('clear', function() {
        this.queue = []
    })
    
    // usage
    var q = new DED.Queue;
    q.setRetryCount(3);
    q.setTimeout(1000);
    q.add({
        method: 'GET',
        'url': 'https://www.baidu.com',
    });
    q.add({
        method: 'GET',
        'url': 'https://www.baidu.com?xiaoming',
    });
    
    q.flush()
    
    // 在真实使用中,可以在添加事件的时候使用桥接函数;
    // 也可以提供一个动作调度函数,桥接用户操作所包含的输入信息并将其委托给恰当的处理代码。
    

    5. 桥接模式的利与弊

    • 利:
      • 将抽象与其实现隔离开,有助于独立地管理软件的各个部分
      • Bug更容易查找
      • 促进代码的模块化,提高抽象的灵活度
      • 可以用来把一组类和函数连接起来,而且提供了一种借助于特权函数访问私有数据的手段
    • 弊:
      • 增加了函数调用次数,对性能有一些负面影响
      • 提高了系统的复杂度
      • 不可滥用

    注意

    转载、引用,但请标明作者和原文地址

  • 相关阅读:
    DataAnnotations
    使用BizTalk实现RosettaNet B2B So Easy
    biztalk rosettanet 自定义 pip code
    Debatching(Splitting) XML Message in Orchestration using DefaultPipeline
    Modifying namespace in XML document programmatically
    IIS各个版本中你需要知道的那些事儿
    关于IHttpModule的相关知识总结
    开发设计的一些思想总结
    《ASP.NET SignalR系列》第五课 在MVC中使用SignalR
    《ASP.NET SignalR系列》第四课 SignalR自托管(不用IIS)
  • 原文地址:https://www.cnblogs.com/CccZss/p/8492303.html
Copyright © 2011-2022 走看看