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
        }
    }
  • 相关阅读:
    归并排序(Merge Sort)
    AtCoder AGC035D Add and Remove (状压DP)
    AtCoder AGC034D Manhattan Max Matching (费用流)
    AtCoder AGC033F Adding Edges (图论)
    AtCoder AGC031F Walk on Graph (图论、数论)
    AtCoder AGC031E Snuke the Phantom Thief (费用流)
    AtCoder AGC029F Construction of a Tree (二分图匹配)
    AtCoder AGC029E Wandering TKHS
    AtCoder AGC039F Min Product Sum (容斥原理、组合计数、DP)
    AtCoder AGC035E Develop (DP、图论、计数)
  • 原文地址:https://www.cnblogs.com/muyuhu/p/3050434.html
Copyright © 2011-2022 走看看