代理模式【设计模式学习-04】

    程式设计中,代理模式是一种设计模式。

    所谓的代理者是指一个类别可以作为其它东西的接口。代理者可以作任何东西的接口:网络连接、内存中的大物件、档案或其它昂贵或无法复制的资源。

著名的代理模式例子为参照计数(英语,reference counting)指标物件。

    当一个复杂物件的多份副本须存在时,代理模式可以结合享元模式以减少内存用量。典型作法是建立一个复杂物件及多个代理者,每个代理者会参照到原本的复杂物件。而作用在代理者的运算会转送到原本物件。一旦所有的代理者都不存在时,复杂物件会被移除。

    代理模式的UML图如下:

     ◇Subject类,定义了RealSubject和Proxy的功用接口,这样就在任何使用RealSubject的地方都可以使用Proxy;

     ◇Proxy类,保存一个引用使得代理可以访问实体,并提供一个与Subject的接口相同的接口,这样代理就可以用来代替实例;

     ◇RealSubject类,定义Proxy所代表的真实实体。

由此图也许我们看不出代理模式意图要表达真实意思,那么我们在看一副图,如下:

    下面给出一个示例程序:

View Code
using System;
using System.Collections.Generic;
using System.Text;

namespace 代理模式
{
class Program
{
static void Main(string[] args)
{
SchoolGirl jiaojiao = new SchoolGirl();
jiaojiao.Name = "李娇娇";

Proxy daili = new Proxy(jiaojiao);

daili.GiveDolls();
daili.GiveFlowers();
daili.GiveChocolate();


Console.Read();
}
}

//送礼物
interface GiveGift
{
void GiveDolls();
void GiveFlowers();
void GiveChocolate();
}

class Proxy : GiveGift
{
Pursuit gg;
public Proxy(SchoolGirl mm)
{
gg = new Pursuit(mm);
}


public void GiveDolls()
{
gg.GiveDolls();
}

public void GiveFlowers()
{
gg.GiveFlowers();
}

public void GiveChocolate()
{
gg.GiveChocolate();
}
}

class Pursuit : GiveGift
{
SchoolGirl mm;
public Pursuit(SchoolGirl mm)
{
this.mm = mm;
}
public void GiveDolls()
{
Console.WriteLine(mm.Name + " 送你洋娃娃");
}

public void GiveFlowers()
{
Console.WriteLine(mm.Name + " 送你鲜花");
}

public void GiveChocolate()
{
Console.WriteLine(mm.Name + " 送你巧克力");
}
}

class SchoolGirl
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}

}

    代理模式适用的场合[引自Gof]:

     ◇远程代理,也就是为一个对象在不同的地址空间提供局部代理。这样可以影藏一个对象存在于不同地址空间的事实。例如WebService在.net中的应用,当我们在应用程序的项目中加入一个web引用,应用一个WebService,此时会在项目中生成一个WebReference文件夹和一些文件,其实他们就是代理。
     ◇虚拟代理,是根据需要创建开销很大的对象。通过他来存放实例化需要很长时间的真实对象。这样新能就可以达到新能的最大化,比如说我们打开一个很大的HTML页面时,里面肯能有很多的文字和图片,但是还是可以很快打开它,此时我们可以很快的看到所有的文字,但图片却是一张一张地下载后才能看到。那些未打开的图片框,就是通过虚拟代理来代替了真实的图片,此时代理村春了真实图像的尺寸和路径。

     ◇安全代理,用来控制真实对象的访问时的权限。一般用在对象应该有不同访问权限的时候。

     ◇智能指引,是指当调用真实的对象时,代理处理另外一些事。例如计算真实对象的引用次数,真阳当对象没有引用是,可以自动释放它;或当第一次引用一个持久对象时,将它装入内存;或在访问一个实际对象前,检查是否已经锁定它,以确保其他对象不能改变它。他们都是通过代理在访问一个对象时附加一些内务处理。 

  

优点

 1 对客户端来说,隐藏了真实对象的细节及复杂性。

 2 实现了客户端(调用者)与真实对象的松耦合。

 3 远程代理使得客户端可以访问在远程机器上的对象,远程机器可能具有更好的性能与处理速度,可以快速响应并处理客户端请求。

 4 虚拟代理通过使用一个小对象来代表一个大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。

 5 安全代理可以控制对真实对象的使用权限。

缺点

 1 实现代理需要而为增加一个访问控制层,增加了额外工作。有的代理实现起来非常复杂。

3 适用场景

 1 远程代理: 为一个位于不同地址空间的的对象提供一个本地的代理。

 2 虚拟代理:如果需要创建一个消耗较大的对象,先创建一个消耗较小的对象来表示,真实对象只在需要时才被真实创建。

 3 安全代理:用来控制对真实对象的访问权限

 4 智能指引:当调用真实对象时,代理提供一些额外的操作。如将对象被操作的次数记录起来等。

 5 缓冲代理:为某一个目标操作提供临时的存储空间,以便更多客户端共享此结果。

 6 防火墙代理:保护目标不让恶意用户接近。

 7 同步化代理:使几个用户能同时使用一个对象而没有冲突。

 

posted @ 2012-03-26 19:50  DebugLZQ  阅读(327)  评论(0编辑  收藏  举报