代理模式
代理概念可以解释为:在出发点到目的地之间有一道中间层,意为代理.
设计模式中的定义:为其他对象提供一种代理以控制对这个对象的访问.
结构图
为什么要使用Proxy?
1.授权机制
不同级别的用户对同一对象拥有不同的访问权限,如Jive论坛系统中,就使用Proxy进行授权机制控制,访问论坛有两种人:注册用户和游客(未注册用户),Jive中就通过类似ForumProxy这样的代理来控制这两种用户对论坛的访问权限.
2.某个客户端不能直接操作到某个对象,但又必须和那个对象有所互动.
举例两个具体情况:
(1)如果那个对象是一个是很大的图片,需要花费很长时间才能显示出来,那么当这个图片包含在文档中时,使用编辑器或浏览器打开这个文档,打开文档必须很迅速,不能等待大图片处理完成,这时需要做个图片Proxy来代替真正的图片.
(2)如果那个对象在Internet的某个远端服务器上,直接操作这个对象因为网络速度原因可能比较慢,那我们可以先用Proxy来代替那个对象.
总之原则是,对于开销很大的对象,只有在使用它时才创建,这个原则可以为我们节省很多宝贵的内存. 所以,有些人认为Net耗费资源内存,我以为这和程序编制思路也有一定的关系.
实用场景:
代理模式非常常用,大致的思想就是通过为对象加一个代理来降低对象的使用复杂度、或是提升对象使用的友好度、或是提高对象使用的效率。在现实生活中也有很多代理的角色,比如明星的经纪人,他就是一种代理,经纪人为明星处理很多对外的事情,目的是为了节省被代理对象也就是明星的时间。保险代理人帮助投保人办理保险,目的降低投保的复杂度。
使用代理模式需要注意以下两点
代理对象和被代理对象都遵循一致的接口。
在某些情况下,可以不必保持接口一致性,如果封装确实需要损失一些透明度,那么也可以认为是Proxy。
代理模式通常使用于对象很复杂或者需要很长时间去构造
代理模式分为以下集中类型
远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是在本机器中,也可是在另一台机器中。远程代理又叫做大使(Ambassador)。
虚拟(Virtual)代理:根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。
Copy-on-Write代理:虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动.StringBuilder就是这种类型的代理
保护(Protect or Access)代理:控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。
Cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
防火墙(Firewall)代理:保护目标,不让恶意用户接近。
同步化(Synchronization)代理:使几个用户能够同时使用一个对象而没有冲突。
智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等
几种与Proxy模式类似模式的异同
Proxy基于一致的接口进行封装,也就是说代理类和被代理类可以说方法基本上相同,可以说实现的同一个接口,但是也有特例。Proxy模式简化的不是接口方法,而是获取或使用对象的途径。
Facade是将内部成员类的几个互相协作的方法封装起来,让其成为一个简化规范的接口,也可以这样说明,定义的接口是内部成员对象的协作方法的组合。他的目的是抽象内部成员对象的方法
Adapter是为了适配接口,将一个现存的接口,适配成另外一个接口。不管是组合适配还是集成适配,他的目的就是通过以实现的类来完成另外一个功能的类
代理模式的实例:
namespace Proxy.Proxy
{
///<summary>
///代理接口如下
///</summary>
public interface GiveGift
{
string GiveDolls();
string GiveFlowers();
string Chocolate();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Proxy.Proxy
{
///<summary>
///功能:实际实现使用的类
///</summary>
public class Pursuit:GiveGift
{
#region GiveGift 成员
SchooleGirl sGirl = new SchooleGirl();
public Pursuit(SchooleGirl sGirl)
{
this.sGirl = sGirl;
}
public string GiveDolls()
{
return sGirl.Name+"送你洋娃娃";
}
public string GiveFlowers()
{
return sGirl.Name + "送你花";
}
public string Chocolate()
{
return sGirl.Name + "送你巧克力";
}
#endregion
}
}
namespace Proxy.Proxy
{
public class SchooleGirl
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
}
namespace Proxy.Proxy
{
///<summary>
///代理类
///</summary>
public class Proxy : GiveGift
{
#region GiveGift 成员
Pursuit gg;
public Proxy(SchooleGirl mm)
{
gg = new Pursuit(mm);
}
public string GiveDolls()
{
return gg.GiveDolls();
}
public string GiveFlowers()
{
return gg.GiveFlowers();
}
public string Chocolate()
{
return gg.Chocolate();
}
#endregion
}
}
namespace Proxy
{
public partial class _Default : System.Web.UI.Page
{
//具体实现
protected void Page_Load(object sender, EventArgs e)
{
SchooleGirl mm = new SchooleGirl();
mm.Name = "李娇娇";
Proxy.Proxy proxy = new global::Proxy.Proxy.Proxy(mm);
Response.Write(proxy.GiveDolls() + proxy.GiveFlowers()+proxy.Chocolate());
}
}
}