zoukankan      html  css  js  c++  java
  • 设计模式--Proxy

    本文转自一下博客:代理模式

    一、 代理(Proxy)模式

    代理(Proxy)模式给某一个对象提供一个代理,并由代理对象控制对原对象的引用。

    代理模式的英文叫做Proxy或Surrogate,中文都可译成"代理"。所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。


    二、 代理的种类

    如果按照使用目的来划分,代理有以下几种:

    • 远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是在本机器中,也可是在另一台机器中。远程代理又叫做大使(Ambassador)。
    • 虚拟(Virtual)代理:根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。
    • Copy-on-Write代理:虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。
    • 保护(Protect or Access)代理:控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。
    • Cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
    • 防火墙(Firewall)代理:保护目标,不让恶意用户接近。
    • 同步化(Synchronization)代理:使几个用户能够同时使用一个对象而没有冲突。
    • 智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。

    在所有种类的代理模式中,虚拟(Virtual)代理、远程(Remote)代理、智能引用代理(Smart Reference Proxy)和保护(Protect or Access)代理是最为常见的代理模式。


    三、 远程代理的例子

    Achilles是一个用来测试网站的安全性能的工具软件。Achilles相当于位于客户端的的一个桌面代理服务器,在一个HTTP过程里起到一个中间人的作用,但是Achilles与通常的代理服务器又有不同。Achilles截获双向的通信数据,使得Achilles软件的用户可以改变来自和发往网络服务器的数据,甚至可以拦截并修改SSL通讯。(这点在《Java与模式》中解释的不是很清楚,关于对非对称密钥加密拦截、破解方法,可以参考我的另外一篇文章《通过代理截取并修改非对称密钥加密信息》)。

    另外一个例子就是Windows的快捷方式。快捷方式是它所引用的程序的一个代理。

    四、 代理模式的结构

    代理模式的类图如下图所示:

    代理模式所涉及的角色有:

    抽象主题角色(Subject):声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题的地方都可以使用代理主题。

    代理主题(Proxy)角色:代理主题角色内部含有对真是主题的引用,从而可以在任何时候操作真实主题对象;代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候都可以替代真实主体;控制真实主题的应用,负责在需要的时候创建真实主题对象(和删除真实主题对象);代理角色通常在将客户端调用传递给真实的主题之前或之后,都要执行某个操作,而不是单纯的将调用传递给真实主题对象。

    真实主题角色(RealSubject)角色:定义了代理角色所代表的真实对象。

    五、 代理模式示例性代码

    以下示例性代码实现了代理模式:

    // Proxy pattern -- Structural example  
    using System;
    
    // "Subject"
    abstract class Subject
    {
      // Methods
      abstract public void Request();
    }
    
    // "RealSubject"
    class RealSubject : Subject
    {
      // Methods
      override public void Request()
      {
        Console.WriteLine("Called RealSubject.Request()");
      }
    }
    
    // "Proxy"
    class Proxy : Subject
    {
      // Fields
      RealSubject realSubject;
    
      // Methods
      override public void Request()
      {
        // Uses "lazy initialization"
        if( realSubject == null )
          realSubject = new RealSubject();
    
        preRequest();
        realSubject.Request();
        postRequest();
      }
    
      public void preRequest()
      { Console.WriteLine("PreRequest."); }
    
      public void postRequest()
      { Console.WriteLine("PostRequest."); }
    }
    
    /// <summary>
    /// Client test
    /// </summary>
    public class Client
    {
      public static void Main( string[] args )
      {
        // Create proxy and request a service
        Proxy p = new Proxy();
        p.Request();
      }
    }
    

      

    六、 代理模式实际应用的例子

    该例子演示了利用远程代理模式提供对另外一个应用程序域(AppDomain)的对象进行访问控制。

    // Proxy pattern -- Real World example
    using System;
    using System.Runtime.Remoting;
    
    // "Subject" 
    public interface IMath
    {
      // Methods
      double Add( double x, double y );
      double Sub( double x, double y );
      double Mul( double x, double y );
      double Div( double x, double y );
    }
    
    // "RealSubject" 
    class Math : MarshalByRefObject, IMath
    {
      // Methods
      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 Div( double x, double y ){ return x / y; }
    }
    
    // Remote "Proxy Object" 
    class MathProxy : IMath
    {
      // Fields
      Math math;
    
      // Constructors
      public MathProxy()
      {
        // Create Math instance in a different AppDomain
        AppDomain ad = System.AppDomain.CreateDomain("MathDomain",null, null );
        ObjectHandle o = ad.CreateInstance("Proxy_RealWorld", "Math", false,
          System.Reflection.BindingFlags.CreateInstance, null, null, null,null,null );
        math = (Math) o.Unwrap();
      }
    
      // Methods
      public double Add( double x, double y )
      { 
        return math.Add(x,y); 
      }
      public double Sub( double x, double y )
      { 
        return math.Sub(x,y); 
      }
      public double Mul( double x, double y )
      { 
        return math.Mul(x,y); 
      }
      public double Div( double x, double y )
      { 
        return math.Div(x,y); 
      }
    }
    /// <summary>
    ///   ProxyApp test
    /// </summary>
    public class ProxyApp
    {
      public static void Main( string[] args )
      {
        // Create math proxy
        MathProxy p = new MathProxy();
    
        // Do the math
        Console.WriteLine( "4 + 2 = {0}", p.Add( 4, 2 ) );
        Console.WriteLine( "4 - 2 = {0}", p.Sub( 4, 2 ) );
        Console.WriteLine( "4 * 2 = {0}", p.Mul( 4, 2 ) );
        Console.WriteLine( "4 / 2 = {0}", p.Div( 4, 2 ) );
      }
    }
    

      

  • 相关阅读:
    模拟队列
    代理模式及java简易实现
    归并排序模板(Java)
    快排Java模板
    durid配置jdbc报错 com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server
    File类
    数据库范式、多表查询,事务
    valuestack(值栈) 和 actioncontext(上下文)
    Action
    Cookie 和Session
  • 原文地址:https://www.cnblogs.com/lihfeiblogs/p/4112904.html
Copyright © 2011-2022 走看看