每天一个设计模式·代理模式

发布时间:2019-10-08 20:15:33编辑:auto阅读(1754)

    博主按:《每天一个设计模式》旨在初步领会设计模式的精髓,目前采用javascript(_靠这吃饭_)和python(_纯粹喜欢_)两种语言实现。诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :)

    0. 项目地址

    1. 什么是代理模式?

    代理模式的定义:为一个对象提供一种代理以方便对它的访问。

    代理模式可以解决避免对一些对象的直接访问,以此为基础,常见的有保护代理和虚拟代理。保护代理可以在代理中直接拒绝对对象的访问;虚拟代理可以延迟访问到真正需要的时候,以节省程序开销。

    2. 代理模式优缺点

    代理模式有高度解耦、对象保护、易修改等优点。

    同样地,因为是通过“代理”访问对象,因此开销会更大,时间也会更慢。

    3. 代码实现

    3.1 python3 实现

    class Image:
      def __init__(self, filename):
        self.filename = filename
    
      def load_img(self):
        print("finish load " + self.filename)
    
      def display(self):
        print("display " + self.filename)
    
    # 借助继承来实现代理模式
    class ImageProxy(Image):
      def __init__(self, filename):
        super().__init__(filename)
        self.loaded = False
    
      def load_img(self):
        if self.loaded == False:
          super().load_img()
        self.loaded = True
    
      def display(self):
        return super().display()
    
    
    if __name__ == "__main__":
      proxyImg = ImageProxy("./js/image.png")
    
      # 只加载一次,其它均被代理拦截
      # 达到节省资源的目的
      for i in range(0,10):
        proxyImg.load_img()
    
      proxyImg.display()

    3.2 javascript 实现

    main.js :

    // main.js
    const myImg = {
      setSrc(imgNode, src) {
        imgNode.src = src;
      }
    };
    
    // 利用代理模式实现图片懒加载
    const proxyImg = {
      setSrc(imgNode, src) {
        myImg.setSrc(imgNode, "./image.png"); // NO1. 加载占位图片并且将图片放入<img>元素
    
        let img = new Image();
        img.onload = () => {
          myImg.setSrc(imgNode, src); // NO3. 完成加载后, 更新 <img> 元素中的图片
        };
        img.src = src; // NO2. 加载真正需要的图片
      }
    };
    
    let imgNode = document.createElement("img"),
      imgSrc =
        "https://upload-images.jianshu.io/upload_images/5486602-5cab95ba00b272bd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp";
    
    document.body.appendChild(imgNode);
    
    proxyImg.setSrc(imgNode, imgSrc);

    main.html :

    <!-- main.html -->
    <!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>每天一个设计模式 · 代理模式</title>
    </head>
    <body>
      <script src="./main.js"></script>
    </body>
    </html>

    4. 参考

关键字

上一篇: Django基础之(十)DRF

下一篇: Holy Python