JavaScript设计模式之代理模式-实现加载图片loading

目录

 

1.定义

2.分类

3.虚拟代理实现加载图片loading

4.为什么要用代理模式?


1.定义

代理模式是为一个对象提供一个代用品或占位符,以便空值对它的访问。

2.分类

  • 虚拟代理:在代理中把一些开销很大的对象,延迟到真正需要它的时候才去创建。
  • 缓存代理:为一些开销大的运算结果提供暂时的存储,在下次运算时,如果传递进来的参数跟之前一致,则可以直接返回前面存储的运算结果。
  • 保护代理:用于对象应该有不同访问权限的情况。
  • 防火墙代理:控制网络资源的访问,保护主题不让“坏人”接近。
  • 远程代理:为一个对象在不同的地址空间提供局部代表,在Java中,远程代理可以是另一个虚拟机中的对象。
  • 智能引用代理:取代了简单的指针,它在访问对象时执行一些附加操作,比如计算一个对象被引用的次数。
  • 写时复制代理:通常用于复制一个庞大对象的情况。写时复制代理延迟了复制的过程,当对象被真正修改时,才对它进行复制操作。写时复制代理是虚拟代理的一种变体,DLL(操作系统中的动态链接库)是其典型运用场景。

代理模式包括许多小分类,在JavaScript开发中最常用的是虚拟代理和缓存代理。

3.虚拟代理实现加载图片loading

实际开发中,会有不少显示图片的需求,当网速差或图片较大的时候,会出现一片空白,这个时候我们就需要有个loading告知用户正在进行加载操作,等到加载完成才显示真实图片,使得体验性更佳。如下图:

  • 不用代理模式实现加载图片loading如下:

    const myImage = (function () {
        const imgNode = document.createElement('img');
        document.body.appendChild(imgNode);
        const img = new Image;
        img.onload = function () {
            imgNode.src = img.src;
        }
        return {
            setSrc: function (src) {
                imgNode.src = 'loading图';
                img.src = src;
            }
        }
    })();
    myImage.setSrc( '真实图片' ); 
  • 用代理模式实现加载图片loading如下:

    // 本体对象
    const myImage = (function () {
        const imgNode = document.createElement('img');
        document.body.appendChild(imgNode);
        return {
            setSrc: function (src) {
                imgNode.src = src;
            }
        }
    })();
    // 代理对象
    const proxyImage = (function () {
        const img = new Image;
        img.onload = function () {
            myImage.setSrc(this.src);          // 加载完成后本体设为真实src
        }
        return {
            setSrc: function (src) {
                myImage.setSrc('loading图片');  // 加载前loading
                img.src = src;                 // 让新建的img加载真实图
            }
        }
    })();
    proxyImage.setSrc('真实显示图片');
  1. 首先创建一个普通的本体对象myImage ,负责往页面中创建一个img标签,并且提供一个对外的setSrc接口,外界调用这个接口设置src属性。
  2. 接着我们引入代理对象proxyImage,通过这个代理对象,在图片被真正加载好之前,页面中将出现一张占位的loading图, 来提示用户图片正在加载;加载完成之后再把本地src设置为真实显示图片。

4.为什么要用代理模式?

我们看到,即使不用任何模式也能实现以上功能,而且代码量更少,那用了代理模式的好处在哪?

当使用代理模式时,更加符合单一职责原则和开放-封闭原则。

  • 单一职责原则:就一个类(通常也包括对象和函数等)而言,应该仅有一个引起它变化的原因。
  • 开放-封闭原则:软件中的对象(类、模块、函数等)应该对于扩展是开放的,但是,对于修改是封闭的。

没有代理模式时,myImage 对象除了负责给img节点设置src外,还要负责显示loading。我们在处理其中一个职责时,有可能因为其强耦合性影响另外一个职责的实现。后面如果因某些情况(图片小、网速快)不需要loading的时候,就需要在MyImage中删除掉相关代码,这就违反了开放-封闭原则。

相反,使用代理模式时,myImage 负责显示图片,proxyImage负责显示loading,它们可以各自变化而不影响对方,符合单一职责原则。代理对象是对于图片加载的扩展,而当我们不需要loading的时候,只需要改成请求本体而不是请求代理对象即可,符合开放-封闭原则。

注:参考书籍《JavaScript设计模式与开发实践》

 

猜你喜欢

转载自blog.csdn.net/qq_39287602/article/details/108747056