代理模式

581 阅读2分钟
原文链接: github.com

代理模式

原理


客户  ==>  代理  ==> 本体

是不是很像如下:


客户端  ==> nginx ==> 服务器

代理模式: 是为一个对象提供一个替代品,准确说是占位符, 用来控制它的访问.

尤其这个对象是一些性能开销很大的对象, 该种代理叫做虚拟代理.


虚拟代理: 把一些开销很大的对象延迟到需要它的时候才创建.

虚拟代理举例说明

  • 图片懒加载

在某些拥有大量图片的页面(电商尤为常见), PC端常用的一种技术叫做图片懒加载(移动端尤其).原理这里就不做介绍了.

主要说下图片懒加载下的虚拟代理实现.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  
</body>
  <script>
    window.onload = function () {
      // 图片懒加载函数
      const myImage = (function (src) {
        let imgNode = document.createElement('img')
        document.body.appendChild(imgNode)
        return {
          setSrc (src) {
            imgNode.src = src
          }
        }
      })()
      // 代理对象
      const proxyImage = (function () {
        const img = new Image();
        img.onload = function () {
          // 加载真正的图片
          myImage.setSrc(this.src)
        }
        return {
          set (url) {
            myImage.setSrc('./1.jpeg') // 本地的loading图片
            img.src = url
          }
        }
      })()
      setTimeout(() => {
        proxyImage.set('https://publish-pic-cpu.baidu.com/4d09f82c-db73-468c-8e5f-9656876891f2.jpeg@f_webp,q_90,w_230')
      }, 5000)
    }
   
  </script>
</html>

上述懒加载功能当然可以直接写在一个函数里面实现:

但是使用代理, 有如下一些好处:


- 细粒度化: 函数各司其职,单一职责原则.
- 降低耦合.方便后期维护或者扩展.

缓存代理

缓存代理: 多用于大量数据计算时候,或者存储时候.为了避免不必要的重复计算,我们可以使用缓存代理,提升代码的性能.减少代码执行时间.

下述以一个计算加法的例子描述缓存代理的使用.



// 处理计算的函数: 求数组中元素的和
const sum = (list) => list.reduce((v, i) => v + i, 0)

// 代理对象
const proxySum = (function () {
  // 缓存对象
  var cache = {}
  return function () {
    // 已缓存的标识符
    let flag = Array.prototype.join.call(arguments, '-')
    if (flag in cache) {
      // 返回缓存
      console.log('返回缓存数据')
      return cache[flag]
    }
    console.log('第一次计算')
    return cache[flag] = sum.apply(this, arguments)
  }
})()

console.log(proxySum([1,2,3,4,5,6,7,8,9,10])) // 第一次计算 55
console.log(proxySum([1,2,3,4,5,6,7,8,9,10])) // 返回缓存数据 55