今天来看看代理模式。首先要理解何为代理模式?啥时候用到代理模式?
当人A要做一件事情,但苦于无法和这个事情的当事人B认识,而使事情特别难办。同时B的一个朋友C也是自己的朋友,这样我们可以委托C去请求B帮忙而达到目的,好处是A不用去认识B。C就是A和B的代理人,起着中间人的作用。
把这个例子放到我们的软件设计中来,A可以放在客户端,起着事件的引导作用。然后C作为A的代理人,牢记A的委托(传递A的实例等)和B接触,然后通过自己自身和B的关系(在C中存有B的实例)和B(事件的响应)接触,最后的部分和A完全没有关系。因此,B一旦发生变化只要C知道就可以了,A(这里代表客户端)完全可以不用理会…这样可以减轻客户端的负担,使软件的维护成本下降。
下面来举一个例子(例子来自《大话设计模式》):
//送礼物
interface GiveGift //送礼物这个行为的接口
{
void GiveDolls();
void GiveFlowers();
void GiveChocolate();
}
送礼物给B是A提出来的,但A和B并不认识,只有C认识B。因此A和C有共同的行为。按面向对象的原则,我们应该把这个行为提升为接口,供A和C来实现。不过在C里面的这个行为的实现是对A的行为实现。
B是一个实体,没有任何的行为。
代码如下:
class B //接受礼物者类
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
A的代码如下:
class A : GiveGift //追求者类,实现GiveGift接口,但没有直接作用于被追求者
{
B b; //送礼物的对象
public A(B b)
{
this.b = b;
}
public void GiveDolls() //这些具体的方法的调用将在代理类里面进行
{
Console.WriteLine(b.Name + " 送你洋娃娃");
}
public void GiveFlowers() //这些具体的方法的调用将在代理类里面进行
{
Console.WriteLine(b.Name + " 送你鲜花");
}
public void GiveChocolate() //这些具体的方法的调用将在代理类里面进行
{
Console.WriteLine(b.Name + " 送你巧克力");
}
}
C作为代理人,代码如下:
class C : GiveGift //代理类,实现GiveGift接口
{
A gg;
public C(B b)
{
gg = new A(b); //在代理类的构造函数里面实例化追求者类的对象
}
public void GiveDolls() //通过代理类的方法去调用追求者类的方法
{
gg.GiveDolls();
}
public void GiveFlowers() //通过代理类的方法去调用追求者类的方法
{
gg.GiveFlowers();
}
public void GiveChocolate() //通过代理类的方法去调用追求者类的方法
{
gg.GiveChocolate();
}
}
如此客户端的代码就好办了:
class Program
{
static void Main(string[] args) //客户端调用
{
B b = new B();
b.Name = "接收礼物的人"; //实例化一个被追求者类的对象
C daili = new C(b); //只有代理人C才认识B
daili.GiveDolls(); //调用代理类的方法,方法里面实际执行的是追求者的方法
daili.GiveFlowers();
daili.GiveChocolate();
Console.Read();
}
}
这个模式其实不难理解,类之间的调用也很明确。多动脑筋,把共同点找出来作为一个接口是关键…