今天继续介绍下Proxy 代理模式 代理模式。Proxy 代理模式是我们开发中挺常见的一种设计模式。当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,所访问的真实对象与代理对象需要实现相同的接口。根据代理模式的使用目的不同,代理模式又可以分为多种类型,例如保护代理、远程代理、虚拟代理、缓冲代理等,它们应用于不同的场合,满足用户的不同需求。(好吧,懒得码字就复制了一波,意思表达到了)。我们先看一个示例代码,理解一下代理模式的原理:
/// <summary>
/// Subject类,定义了RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方偶读可以使用Proxy
/// </summary>
abstract class Subject
{
public abstract void Request();
}
/// <summary>
/// RealSubject类,定义Proxy所代表的真实实体
/// </summary>
class RealSubject : Subject
{
public override void Request()
{
Console.WriteLine("真实的请求");
}
}
/// <summary>
/// Proxy类,保存一个引用使得代理可以访问实体,并提供一个与Subject的接口相同的接口,这样代理就可以用来代替实体
/// </summary>
class Proxy : Subject
{
RealSubject realSubject;
public override void Request()
{
if (realSubject == null)
{
realSubject=new RealSubject();
}
realSubject.Request();
}
}
首先是定义一个Subject虚类, 然后实现一个它的子类RealSubject ,同时继承了他的方法Request ,在子类中实现需要做的真实请求。然后就是我们的代理类Proxy, 继承 虚类Subject, 同时Proxy类中也存放一个子类RealSubject 的引用,然后在重写Request方法中去调用RealSubject 的方法,这个就是代理类的基础使用原理,咋一看好像没什么卵用,就和你写一个私有字段,然后在写公有的字段 给私有字段用Get和Set方法保护起来类似。 普通字段用公有和私有分开,达到保护的作用,而代理模式就是保护一个类,保护一个方法。但你以为就是这样吗? 是的 ,你猜对了,就是这么简单,不过,这样做其实还有好多好处,比如我们设计一个充值的功能,我们肯定不能让用户去写要充值的数值,或者说让用户可以自由访问充值的数值和金额,这样很有可能会让用户改变,达到作弊的手段,我们就可以用一个代理的方法把充值这块包起来,用户只要告诉我们 要充值的是哪个选项(套餐)就可以了,其他事情都在代理类的实体类处理。讲了这么多,我们在看来看运行代码和情况:
public sample()
{
Proxy proxy=new Proxy();
proxy.Request();
Console.Read();
}
我们new了代理类Proxy,然后运行代理类的方法Request() 其实就调用了代理类里面的实际类RealSubject的方法了:
我们在来写个示例练练手,就拿刚才说的充值来说:
/// <summary>
/// 充值角色类
/// </summary>
class TopUpClient
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
/// <summary>
/// 充值接口类
/// </summary>
interface TopUp
{
void Topup10Yuan();
void Topup20Yuan();
void Topup100Yuan();
}
/// <summary>
/// 客户端
/// </summary>
class Client : TopUp
{
private TopUpClient TClient;
public Client(TopUpClient mm)
{
this.TClient = mm;
}
public void Topup100Yuan()
{
Console.WriteLine("充值100元给:"+TClient.Name);
}
public void Topup10Yuan()
{
Console.WriteLine("充值10元给:" + TClient.Name);
}
public void Topup20Yuan()
{
Console.WriteLine("充值20元给:" + TClient.Name);
}
}
/// <summary>
/// 代理充值类
/// </summary>
class ProxyTopUp : TopUp
{
Client client;
public ProxyTopUp(TopUpClient tc)
{
client=new Client(tc);
}
public void Topup10Yuan()
{
client.Topup10Yuan();
}
public void Topup20Yuan()
{
client.Topup20Yuan();
}
public void Topup100Yuan()
{
client.Topup100Yuan();
}
}
首先定义一个充值角色类TopUpClient 代表客户端 ,里面存放了名字。 然后是充值接口类TopUp,里面有几个虚方法,代表充值的金额。
再来个客户端类Client,继承充值接口类TopUp。里面还有一个客户端TopUpClient 的引用。 好了 实际功能的类都写好了,最后到咱们的 代理类ProxyTopUp , 继承继承充值接口类TopUp,有客户端类Client的引用,实现方法,都去调用客户端类Client的方法。方法写好了,最后看看运行代码:
TopUpClient tc = new TopUpClient();
tc.Name = "爱德华";
ProxyTopUp ProxyTu = new ProxyTopUp(tc);
ProxyTu.Topup10Yuan();
ProxyTu.Topup20Yuan();
ProxyTu.Topup100Yuan();
Console.ReadKey();
new 一个客户端类,命名叫爱德华(爱德华冲啊)
new 一个代理类,传入这个客户端,然后我们运行代理类,代理类就会运行我们客户端类的代码了。
![](http://img.manew.com/data/attachment/forum/201611/14/111251gqfe7t0qnd1yneqm.jpg.thumb.jpg)
(1) 远程代理(Remote Proxy):为一个位于不同的地址空间的对象提供一个本地的代理对象,这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又称为大使(Ambassador)。
(2) 虚拟代理(Virtual Proxy):如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。
(3) 保护代理(Protect Proxy):控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。
(4) 缓冲代理(Cache Proxy):为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
(5) 智能引用代理(Smart Reference Proxy):当一个对象被引用时,提供一些额外的操作,例如将对象被调用的次数记录下来等。