• Proxy模式简介和用例


        在软件系统中,有些对象有时候由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),如果直接访问会给使用者或者系统结构带来很多麻烦,这时可以在客户程序和目标对象之间增加一层中间层,这个中间层就是代理。

        代理模式的定义:给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

    代理模式可分为以下几类:

    (1)远程代理:为一个位于不同的地址空间的对象提供一个局域代表对象。好处是系统可以将网络的细节隐藏起来,使得客户端不必考虑网络的存在。

    (2)保护代理:控制对一个对象的访问,如果需要可以给不同的用户提供不同级别的使用权限。好处是它可以在运行时间对用户的有关权限进行检查,然后在核实后决定将调用传递给被代理的对象。

    (3)虚拟代理:根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。好处是代理对象可以在必要的时候才将被代理的对象加载。

    (4)智能引用代理:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。

    这里给出两个使用该模式的例子:

    应用一:虚拟代理

    例如:word文档打开

    Word文档通常会含有链接、图片、表格等对象,但是并不是每次刚打开word时都要创建和实例化这些对象,特别是实例化图片对象很消耗资源。事实上,我们没必要实例化所有图片,当我们在查看word时,每次只是看到其中的一部分,所以没有必要实例化所有资源,可以使用一个虚代理物件,代替图片被载入,来加快打开文档速度,当我们看下一页时再载入图片也不迟。

    类图如图所示:

    如上图所示,当文档被开启时, ProxyImage代理代替RealImage物件被载入,在还没卷动至图片显示处时,也就是还没有调用 ProxyImage的Draw()时,图片并不会被载入,因而可以加速文档的开启;如果需要显示图片了, ProxyImage的 Draw()会被调用,而这时才真正创建RealImage物件,以从硬盘中载入图片。

    主要类代码:

    public interface Image //Image公共接口
    
     {
    
         public abstract void Draw();
    
     }
    
    //ProxyImage类实现Image接口
    
    public class ProxyImage implements Image
    
    {
    
         private RealImage realimage;
    
    public void Draw()
    
    {
    
        If(realimage==NULL)
    
    {
    
        Realimage=new RealImage();
    
    }
    
    realimage.Draw();
    
    }
    
     }
    
    //RealImage类实现Image接口
    
    public class RealImage implements Image
    
     {
    
    public void Draw()
    
    { Console.WriteLine(“载入图片……”);}
    
     }
    
    主程序
    
    public class App
    
     {
    
         public static void Main()
    
         {
    
             ProxyImage proxy = new ProxyImage();
    
             proxy.Draw();
    
         }
    
     }

    应用二:远程访问

    例子:远程数学运算访问

    本地客户程序需要调用远程服务器提供的数学运算服务,也就是说数学运算服务和客户程序不在同一个地址空间之内,我们现在要面对的是跨越Internet这样一个网络障碍:这时候调用数学运算服务就没有下面那么简单了,因为我们更多的还要去考虑网络的问题,对接收到的结果解包等一系列操作。为了避免由于网络等障碍引起的复杂性,引用Proxy模式,用一个本地的代理来代替远程数学运算类打点一切,即为我们的系统引入了一层间接层,示意图如下

    设计的类图如下:

    如上图所示:我们在ProxMath中对实现数据类的访问,让ProxyMath来代替网络上的RealMath类,这样我们看到ProxMathy就好像是本地RealMath类,它与客户程序处在了同一地址空间内。

    主要代码:

    View Code
    public interface Math //Math公共接口
    
     {
    
         public abstract double Add(double x,double y);
    
         public abstract double Sub(double x,double y);
    
         public abstract double Mul(double x,double y);
    
         public abstract double Dev(double x,double y);
    
     }
    
    public class ProxyMath implements Math //Proxy类,继承于Math
    
     {
    
         private RealMath realmath = new RealMath();
    
         //Proxy类中不光有调用Math类的方法,还包含一些网络通信,与远程服务器交换数据,此处省略。
    
         public double Add(double x,double y)
    
         {
    
             return math.Add(x,y);
    
         }
    
         public double Sub(double x,double y)
    
         {
    
             return realmath.Sub(x,y);
    
         }
    
         public double Mul(double x,double y)
    
         {
    
             return realmath.Mul(x,y);
    
         }
    
         public double Dev(double x,double y)
    
         {
    
             return realmath.Dev(x,y);
    
         }
    
     }
    
    public class RealMath implements Math
    
     {
    
         public double Add(double x,double y)
    
         {
    
             return x + y;
    
         }
    
         public double Sub(double x,double y)
    
         {
    
             return x - y;
    
         }
    
         public double Mul(double x,double y)
    
         {
    
             return x * y;
    
         }
    
         public double Dev(double x,double y)
    
         {
    
             return x / y;
    
         }
    
     }
    
    测试主程序
    
    public class App
    
     {
    
         public static void Main()
    
         {
    
             ProxyMath proxy = new ProxyMath();
    
             double addresult = proxy.Add(2,3);
    
             double subresult = proxy.Sub(2,3);
    
             double mulresult = proxy.Mul(2,3);
    
             double devresult = proxy.Dev(2,3);
    
         }
    
     }

    从上面的两个例子可以概括出Proxy模式的工作原理:

    首先,代理并不改变主题的接口,因为模式的用意是不让客户端感觉到代理的存在;其次,代理使用委派将客户端的调用委派给真实的主题对象,换言之,代理起到的是一个传递请求的作用;第三,代理在传递请求之前和之后都可以执行特定的操作(如网络通信、检查对象是否存在等),而不是单纯传递请求。

  • 相关阅读:
    开源协议
    开发新技能
    UML 思维导图 思维脑图 xmind
    小方法
    Android Service
    JS 下载图片
    quartz任务执行完之后再执行下一轮任务
    easyui 下边有滚动条问题
    微信支付证书 系统找不到指定的文件
    Swiper 动态加载数据没有变化问题
  • 原文地址:https://www.cnblogs.com/Yogurshine/p/2831860.html
Copyright © 2020-2023  润新知