代理模式为其他对象提供一种代理,以控制对这个对象的访问。所谓代理,就是真实对象的代表。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。举个例子,网易是暴雪在中国大陆的代理,暴雪为什么不在中国直接运营,却要通过网易作为代理呢?这是因为暴雪公司在美国,如果让游戏玩家通过网络连接到美国的游戏服务器,那将是一种恐怖到令人无法想象的情形。
1.角色:
抽象主题角色(Subject)
代理主题角色(Proxy)
真实主题角色(RealSubject)
结构图:
真正对象与代理对象实现同一个接口,先访问代理类再访问真正要访问的对象。
2.优缺点
代理对象在客户端和目标对象之间起到中介的作用,保护了目标对象;能够协调调用者与被调用者,在一定程度上降低了系统的耦合度.;增强了扩展性,使角色职责清晰。
缺点:
由于增加了代理,会造成请求的处理速度变慢,而且有些代理模式的实现比较复杂。
3.应用:
(1)远程代理:
为一个对象在不同的地址空间提供局部代表,可以隐藏一个对象存在不同地址空间的事实。
(2)虚拟代理:
根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象,使得此对象只在需要时才会被真正创建 。
(3)安全代理:
用来控制真实对象访问时的权限,可以给不同的用户提供不同级别的使用权限。
(4)智能指引:
当调用真实的对象时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。
4.代码示范:
需求:追求者通过代理给心仪的女孩送礼物。
结构图:
代理接口:
interface GiveGift //送礼物接口
{
void GiveDolls();
void GiveFlowers();
void GiveChocolate();
}
被追求者类:
class SchoolGirl
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
追求者类:
class Pursuit : GiveGift //追求者实现“送礼物”接口
{
SchoolGirl mm;
public Pursuit(SchoolGirl mm)
{
this.mm = mm;
}
public void GiveDolls()
{
Console.WriteLine(mm.Name + " 送你洋娃娃");
}
......
}
代理类:
class Proxy : GiveGift //代理类实现“送礼物”接口
{
Pursuit gg;
public Proxy(SchoolGirl mm)
{
gg = new Pursuit(mm);
}
public void GiveDolls()
{
gg.GiveDolls(); //在实现方法中调用追求者类的相关方法
}
......
}
客户端:
static void Main(string[] args)
{
SchoolGirl jiaojiao = new SchoolGirl();
jiaojiao.Name = "李娇娇";
Proxy daili = new Proxy(jiaojiao);
daili.GiveDolls();
daili.GiveFlowers();
daili.GiveChocolate();
Console.Read();
}
效果图:
代理模式的本质就是迂回战术,通过添加一个中间层来解决问题,它是软件系统中很常见的一个模式。代理一般实现的功能都是连接到服务器并进行数据下载和数据翻译以及本土化处理等操作,之后代理再将这些数据传送给本地的客户去使用。代理模式的应用使得客户端的压力大大减少,提升了客户的数目。