浅谈代理模式和迭代器模式

79 阅读1分钟

代理模式

  • 定义: 代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对象

  • 代理模式又分为保护代理和虚拟代理

  • 代理对象和本体需要有相同的接口 (规范)

举个例子1,创建一个虚拟代理实现图片预加载

let myImage = (function () { 
    let img = document.createElement('img');
    document.body.appendChild(img);
    return {
        setImgSrc: function (src) { 
            img.src = src
        }
    }
})()

// 创建一个虚拟代理,在图片加载完成前使用一个gif图占位

let proxyMyImage = (function () { 
    let img = new Image();
    img.onLoad = function () { 
        myImage.setImgSrc(this.src)
    }
    return {
        setSrc: function (src) { 
            myImage.setImgSrc('C://file.gif');
            img.src = src
        }
    }
})()

// 代理做了两件事:
// 1:将占位图给之前的标签;
// 2:创建一个image标签,将图片下载到本地
// 3、监听image标签onLoad事件,将之前的image标签的src替换

举个例子2: 实现一个缓存代理,将结果存储在cache中,假如有cache中有,则不需要再重新计算

    const product = function () { 
    let sum = 1
    for (let i = 0; i < arguments.length; i++) { 
        sum = sum * arguments[i]
    }
    return sum
}

const proxyProduct = (function () { 
    let cache = {}
    return function () { 
        let arg = Array.prototype.join.call(arguments, ';')
        if (!cache[arg]) { 
            cache[arg] = product.apply(this, arguments)
        }
        return cache[arg]
    }
})()

console.log(proxyProduct(1, 2, 3))

迭代器模式

  • 定义: 迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素, 而又不需要暴露该对象的内部表示。迭代器模式可以把迭代的过程从业务逻辑中分离出来, 在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素

  • 迭代器模式的实质: 循环访问对象的各个元素。 比如: forEach

例子1: 实现一个简单的迭代器


    let each = function (arr, callback) { 
        for (let i = 0; i < arr.length; i++) { 
            callback.call(this, i, arr[i])
        }
    }

    each([1, 2, 3], (i, item) => { 
        console.log(i, item)
    })

例子2: 迭代不同的上传方式,直到上传成功为止

    var getActiveUploadObj = function(){
    try{
      return new ActiveXObject( "TXFTNActiveX.FTNUpload" );    // IE上传控件
    }catch(e){
      return false;
    }
};

var getFlashUploadObj = function(){
    if ( supportFlash() ){     // supportFlash函数未提供
      var str = '<object type="application/x-shockwave-flash"></object>';
      return $( str ).appendTo( $('body') );
    }
    return false;
};
var getFormUpladObj = function(){
    var str = '<input name="file" type="file" class="ui-file"/>';  // 表单上传
    return $( str ).appendTo( $('body') );
};

var iteratorUploadObj = function(){
    for ( var i = 0, fn; fn = arguments[ i++ ]; ){
      var uploadObj = fn();
      if ( uploadObj ! == false ){
          return uploadObj;
      }
    }
};

var uploadObj = iteratorUploadObj( getActiveUploadObj, getFlashUploadObj, getFormUpladObj );


  • 迭代器模式和策略模式都能解决大量if else的问题