zoukankan      html  css  js  c++  java
  • 代理模式

    1、代理模式的定义:

    为其他对象提供一种代理以控制对这个对象的访问。简而言之就是用一个对象来代表另一个对象。

    2、代理模式的目的:

    提供其他对象一个代理或占位符,来控制该对象的访问权限。为什么我们要控制对象的访问权限呢?其中一个原因是通过控制来延迟对象的创建和实例化,直到真正需要使用该对象才进行创建和实例化。由于一些对象创建和实例化需要占用大量系统资源,但我们并不能确定用户一定会调用该对象,所以通过延迟对象实例化来减缓系统资源的消耗。例如文档编辑器如word,我们可以在里面插入链接、图片等,但是并不是我们每次打开word时都有创建和实例化这些对象,特别是实例化图片对象很消耗资源,而且我们有必要实例化所有图片吗?当我们在查看word时,只是看到其中的一部分,所以没有必要实例化所以资源,当我们看下一页时再实例化也不迟。

    3、代理模式的应用:

    需要用比较通用和复杂的对象指针代替简单的指针的时候,使用 Proxy模式。下面是一些可以使用Proxy模式常见情况:
    1) 远程代理(Remote  Proxy)为一个位于不同的地址空间的对象提供一个本地的代理对象。这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又叫做大使(Ambassador)
    2) 虚拟代理(Virtual Proxy)根据需要创建开销很大的对象。如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。 
    3) 保护代理(Protection Proxy)控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。
    4) 智能指引(Smart Reference)取代了简单的指针,它在访问对象时执行一些附加操作。
    5) Copy-on-Write代理:它是虚拟代理的一种,把复制(克隆)操作延迟到只有在客户端真正需要时才执行。一般来说,对象的深克隆是一个开销较大的操作,Copy-on-Write代理可以让这个操作延迟,只有对象被用到的时候才被克隆。

    使用代理模式达到的效果

    1) Remote Proxy可以隐藏一个对象存在于不同地址空间的事实。也使得客户端可以访问在远程机器上的对象,远程机器可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。
    2) Virtual Proxy 可以进行最优化,例如根据要求创建对象。即通过使用一个小对象来代表一个大对象,可以减少系统资源的消耗。
    3) Protection Proxies和Smart Reference都允许在访问一个对象时有一些附加的内务处理(Housekeeping task) 。

    4、代理模式的结构图:

    clip_image001

    简单结构示意图:



    1)代理角色(Proxy):
    . 保存一个引用使得代理可以访问实体。若 RealSubject和Subject的接口相同,Proxy会引用Subject。
    . 提供一个与Subject的接口相同的接口,这样代理就可以用来替代实体。
    . 控制对实体的存取,并可能负责创建和删除它。
    . 其他功能依赖于代理的类型:
    • Remote Proxy负责对请求及其参数进行编码,并向不同地址空间中的实体发送已编码的请求。
    • Virtual Proxy可以缓存实体的附加信息,以便延迟对它的访问。
    • Protection Proxy检查调用者是否具有实现一个请求所必需的访问权限。
    2) 抽象主题角色(Subject):定义真实主题角色RealSubject 和 抽象主题角色Proxy的共用接口,这样就在任何使用RealSubject的地方都可以使
    用Proxy。代理主题通过持有真实主题RealSubject的引用,不但可以控制真实主题RealSubject的创建或删除,可以在真实主题RealSubject被调用前进行拦截,或在调用后进行某些操作. 

    3) 真实主题角色(RealSubject):定义了代理角色(proxy)所代表的具体对象. 

    6、 代理模式实例:

    import java.util.*; 
    interface Image {
        public void displayImage();
    }
     
    //on System A 
    class RealImage implements Image {
        private String filename;
        public RealImage(String filename) { 
            this.filename = filename;
            loadImageFromDisk();
        }
     
        private void loadImageFromDisk() {
            System.out.println("Loading   " + filename);
        }
     
        public void displayImage() { 
            System.out.println("Displaying " + filename); 
        }
    }
     
    //on System B 
    class ProxyImage implements Image {
        private String filename;
        private Image image;//在代理类中声明一个被代理类对象的引用。
     
        public ProxyImage(String filename) { 
            this.filename = filename; 
        }
        public void displayImage() {
            if(image == null)
                  image = new RealImage(filename);
            image.displayImage();//在代理类中用被代理对象调用被代理对象的方法。
        }
    }
     
    class ProxyExample {
        public static void main(String[] args) {
            Image image1 = new ProxyImage("HiRes_10MB_Photo1");
            Image image2 = new ProxyImage("HiRes_10MB_Photo2");     
     
            image1.displayImage(); // loading necessary这里调用代理类的display方法,实际是调用的被代理类的display方法
            image2.displayImage(); // loading necessary
        }
    }
  • 相关阅读:
    vue vant 循环picker模块的实现方法
    Element的表单验证规则,清空或填充数据如何避免自动触发
    递归寻找树结构的子节点
    vue源码解析实例(二)---vue 虚拟DOM篇
    vue源码解析实例(一)
    变化侦测篇---Object.create(null)的定义
    vue源码-变化侦测篇(小知识点)
    Vue源码学习-开篇
    position: sticky轻松做出吸顶功能
    自适应图片高度蒙层 css
  • 原文地址:https://www.cnblogs.com/muyuhu/p/3050434.html
Copyright © 2011-2022 走看看