代理模式的定义是:为某个对象提供种代理以控制对这个对象的访问。这里所谓的代理是所要代理的对象的一个外覆对象,要想访问真正的对象,必须通过它的外覆类(代理对象),代理对象主要有四种用途:
-
远程代理,为一个对象在不同的地址空间提供局部代表。
-
虚代理,根据需要创建开销很大的对象时,并不是真正立即创建这个对象,而是创建一个包含必要信息的代理对象,只有不得不初始化开销很大的对象时才真正创建需要的对象,从而优化性能。
-
保护代理,控制外部对被代理对象的访问。
-
指正指针,提供对底层指针的安全访问功能,负责处理底层指针的初始化与释放等。
洪兴社扛把子很忙的,很多事情他没时间处理,也不必他处理,但是又不得不应对,所以他请了一个助理来帮助他。
namespace HongXingHeaderProxy
{
public class Person
{
public Person(stringname)
{
if (name == null)
{
throw newArgumentNullException();
}
else
{
this.name =name;
}
}
protected string name;
public string Name
{
set
{
name = value;
}
get
{
return name;
}
}
}
//有很多访问者会来拜访洪兴老大
public class Visitor :Person
{
public Visitor(stringname)
: base(name)
{
}
}
//洪兴老大再厉害,也是个人
public class HongXingHeader : Person
{
publicHongXingHeader(string name)
: base(name)
{
}
//签合约这种事情,老大是不得不亲自经手的,不然他睡不安稳
public void SignContract(Visitor visitor)
{
if(AgreeToHandEvent(visitor))
Console.WriteLine("我洪兴社老大{0},我同意这份合约!",name);
else
Console.WriteLine("我是洪兴社老大{0},我不同意这份合约!",name);
}
//只要是小布什请求签约,老大一定不答应,其他的都答应,
//他不会告诉助理他有这条规则的
public bool AgreeToHandEvent(Visitor visitor)
{
bool IsVisit =false;
if (visitor !=null && visitor.Name == "小布什")
IsVisit =true;
return IsVisit;
}
}
//代理也是个人
public classHongXingHeaderProxy : Person
{
private stringheaderName = null;
public stringHeaderName
{
set
{
headerName =value;
}
get
{
returnheaderName;
}
}
//代理内含被代理的对象
private HongXingHeadertheThreeFederalHeader = null;
//创建代理时并不真正创建被代理者,仅需要持有必要的信息(老大的名字)
public HongXingHeaderProxy(string name,string headerName)
: base(name)
{
this.headerName =headerName;
}
//这个时候就不得不创建被代理对象了,如果不创建,事情没法进行
private void AskHeaderToHandEvent()
{
if(theThreeFederalHeader == null)
{
theThreeFederalHeader = new HongXingHeader(headerName);
}
}
//签约这事,代理是没法做的,只能是被代理者亲自做
public void SignContract(Visitor visitor)
{
AskHeaderToHandEvent();
theThreeFederalHeader.SignContract(visitor);
}
//发生这种事的时候,当然不需要在被代理对象被初始化之后嘛
public void ShowHeaderName()
{
Console.WriteLine("我的老大是{0}!", headerName);
}
//火星人来访?代理知道老大不会接待的,控制了外部对被代理对象的访问
public void AMartianAskToSeeTheHeader()
{
Console.WriteLine("老板不在,请回去吧!");
}
}
}
上面的代码主要表明了代理的两种用途:虚代理和保护代理,下面来测试一下吧。使用代码生成工具(见前面的文章)输入模式名Proxy,选择覆写RunTest函数,再勾选“设为当前测试模式”,就可以得到代理模式的测试子类,然后编写RunTest函数体,如下:
namespace DesignPatternProject
{
class ProxyPatternTester :IPatternTester
{
protected overridevoid RunTest()
{
HongXingHeaderProxy.HongXingHeaderProxy hongXinHeaderProxy = newHongXingHeaderProxy.HongXingHeaderProxy("王青霞","陈浩南");
//此时代表老大的对象并没有创建
hongXinHeaderProxy.ShowHeaderName();
Console.WriteLine("__________________________________");
Visitor visitor1 =new Visitor("小布什");
Visitor visitor2 =new Visitor("奥巴马");
//此时必须创建代表老大的对象
hongXinHeaderProxy.SignContract(visitor1);
Console.WriteLine("__________________________________");
hongXinHeaderProxy.SignContract(visitor2);
Console.WriteLine("__________________________________");
//此时代表老大的对象创建与否,没有关系,代理可以完成对这件事的反//应
hongXinHeaderProxy.AMartianAskToSeeTheHeader();
}
}
}
编译、运行,得到如下结果:
好了,代理模式就是这么简单,另外两个用途请参考其他例子吧~想要更好的理解,一定要读经典哦!个人的感觉是,只有亲自去实践了各种模式的做法才能对各种模式的动机与所带来的好处用很深刻的理解。