设计模式之Proxy代理模式


意图intent:为其他对象提供一种代理以控制对这个对象的访问。

适用性:

  • 在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy模式。下面是一些可以使用Proxy模式常见情况:
    1)
    远程代理(Remote Proxy)为一个对象在不同的地址空间提供局部代表。 NEXTSTEP[Add94] 使用NX
    Proxy类实现了这一目的。Coplien[Cop92] 称这种代理为大使Ambassador)。
    2 )
    虚代理(Virtual Proxy)根据需要创建开销很大的对象。在动机一节描述的ImageProxy就是这样一种代理的例子。
    3)
    保护代理(Protection Proxy)控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。例如,在Choices操作系统[CIRM93]KemelProxies为操作系统对象提供了访问保护。
    4 )
    智能指引(Smart Reference)取代了简单的指针,它在访问对象时执行一些附加操作。它的典型用途包括:
  • 对指向实际对象的引用计数,这样当该对象没有引用时,可以自动释放它(也称为SmartPointers[Ede92])
  • 当第一次引用一个持久对象时,将它装入内存。
  • 在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。

Definition

Provide a surrogate or placeholder for another object to control access to it. 

participants

    The classes and/or objects participating in this pattern are:

  • Proxy   (MathProxy)
    • maintains a reference that lets the proxy access the real subject. Proxy may refer to a Subject if the RealSubject and Subject interfaces are the same.
    • provides an interface identical to Subject's so that a proxy can be substituted for for the real subject.
    • controls access to the real subject and may be responsible for creating and deleting it.
    • other responsibilites depend on the kind of proxy:
      • remote proxies are responsible for encoding a request and its arguments and for sending the encoded request to the real subject in a different address space.
      • virtual proxies may cache additional information about the real subject so that they can postpone accessing it. For example, the ImageProxy from the Motivation caches the real images's extent.
      • protection proxies check that the caller has the access permissions required to perform a request.
  • Subject   (IMath)
    • defines the common interface for RealSubject and Proxy so that a Proxy can be used anywhere a RealSubject is expected.
  • RealSubject   (Math)
    • defines the real object that the proxy represents.

Proxy模式的作用就是用Proxy来代替RealSubject。因为RealSubject可能不方便提供给别人使用,而RealSubjectProxy都是继承自Subject,所以在可以使用RealSubject的地方也都可以使用ProxyProxy把接收过来的请求又调用RealSubject,因为Proxy类里面拥有一个RealSubject的实例对象。

sample code in C#

This structural code demonstrates the Proxy pattern which provides a representative object (proxy) that controls access to another similar object.

// Proxy pattern -- Structural example

 

using System;

namespace DoFactory.GangOfFour.Proxy.Structural
{
  
  // MainApp test application

  class MainApp
  {
    static void Main()
    {
      // Create proxy and request a service
      Proxy proxy = new Proxy();
      proxy.Request();

      // Wait for user
      Console.Read();
    }
  }

  // "Subject"

  abstract class Subject
  {
    public abstract void Request();    
  }

  // "RealSubject"

  class RealSubject : Subject
  {
    public override void Request()
    {
      Console.WriteLine("Called RealSubject.Request()");
    }
  }

  // "Proxy"

  class Proxy : Subject
  {
    RealSubject realSubject;

    public override void Request()
    {
      // Use 'lazy initialization'
      if (realSubject == null)
      {
        realSubject = new RealSubject();
      }

      realSubject.Request();
    }  
  }
}

 

Output

Called RealSubject.Request()

 

This real-world code demonstrates the Proxy pattern for a Math object represented by a MathProxy object.

// Proxy pattern -- Real World example

 

using System;

namespace DoFactory.GangOfFour.Proxy.RealWorld
{
  
  // Mainapp test application

  class MainApp
  {
    static void Main()
    {
      // Create math proxy
      MathProxy p = new MathProxy();

      // Do the math
      Console.WriteLine("4 + 2 = " + p.Add(4, 2));
      Console.WriteLine("4 - 2 = " + p.Sub(4, 2));
      Console.WriteLine("4 * 2 = " + p.Mul(4, 2));
      Console.WriteLine("4 / 2 = " + p.Div(4, 2));

      // Wait for user
      Console.Read();
    }
  }

  // "Subject"

  public interface IMath
  {
    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 : IMath
  {
    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;}
  }

  // "Proxy Object"

  class MathProxy : IMath
  {
    Math math;

    public MathProxy()
    {
      math = new Math();
    }

    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);
    }
  }
}

 

Output

4 + 2 = 6

4 - 2 = 2

4 * 2 = 8

4 / 2 = 2

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值