代理模式【设计模式学习-04】
程式设计中,代理模式是一种设计模式。
所谓的代理者是指一个类别可以作为其它东西的接口。代理者可以作任何东西的接口:网络连接、内存中的大物件、档案或其它昂贵或无法复制的资源。
著名的代理模式例子为参照计数(英语,reference counting)指标物件。
当一个复杂物件的多份副本须存在时,代理模式可以结合享元模式以减少内存用量。典型作法是建立一个复杂物件及多个代理者,每个代理者会参照到原本的复杂物件。而作用在代理者的运算会转送到原本物件。一旦所有的代理者都不存在时,复杂物件会被移除。
代理模式的UML图如下:
◇Subject类,定义了RealSubject和Proxy的功用接口,这样就在任何使用RealSubject的地方都可以使用Proxy;
◇Proxy类,保存一个引用使得代理可以访问实体,并提供一个与Subject的接口相同的接口,这样代理就可以用来代替实例;
◇RealSubject类,定义Proxy所代表的真实实体。
由此图也许我们看不出代理模式意图要表达真实意思,那么我们在看一副图,如下:
下面给出一个示例程序:
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 同步化代理:使几个用户能同时使用一个对象而没有冲突。