您的位置:首页 > 其它

设计模式之Proxy代理模式

2006-11-17 23:32 579 查看
意图intent:为其他对象提供一种代理以控制对这个对象的访问。
适用性:

在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy模式。下面是一些可以使用Proxy模式常见情况:
1) 远程代理(Remote Proxy)为一个对象在不同的地址空间提供局部代表。 NEXTSTEP[Add94] 使用NXProxy类实现了这一目的。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可能不方便提供给别人使用,而RealSubject和Proxy都是继承自Subject,所以在可以使用RealSubject的地方也都可以使用Proxy。Proxy把接收过来的请求又调用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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: