一个男生卓贾易追求一个女生李娇娇,两人并不认识,但两人有共同的好友戴励。代码如何写?
版本一
最开始很容易想到——
结构图:
追求者类:
class Pursuit{
SchoolGirl mm;
public Pursuit(SchoolGirl mm){
this.mm = mm;
}
public void GiveDolls(){
Console.WriteLine(mm.Name + "送你洋娃娃");
}
public void GiveFlowers(){
Console.WriteLine(mm.Name + "送你鲜花");
}
public void GiveChocolate(){
Console.WriteLine(mm.Name + "送你巧克力");
}
}
被追求者类:
class SchoolGirl{
private string name;
public string Name{
get{return name;}
set{name=value;}
}
}
客户端调用代码如下:
static void Main(string[] args){
SchoolGirl jiaojiao = new SchoolGirl();
jiaojiao.Name="李娇娇";
Pursuit zhuojiayi = new Pursuit(jiaojiao);
zhuojiayi.GiveDolls();
zhuojiayi.GiveFlowers();
zhuojiayi.GiveChocolate();
Console.Read();
}
但是注意题设,卓贾易和李娇娇并不认识,那么调用
Pursuit zhuojiayi = new Pursuit(jiaojiao);
就有问题。
怎么办?事情好像都是戴励做的,就像个代理一样,我们把追求者类换成代理?
版本二
结构图:
代理类:
class Proxy{
SchoolGirl mm;
public Pursuit(SchoolGirl mm){
this.mm = mm;
}
public void GiveDolls(){
Console.WriteLine(mm.Name + "送你洋娃娃");
}
public void GiveFlowers(){
Console.WriteLine(mm.Name + "送你鲜花");
}
public void GiveChocolate(){
Console.WriteLine(mm.Name + "送你巧克力");
}
}
客户端代码:
static void Main(string[] args){
SchoolGirl jiaojiao = new SchoolGirl();
jiaojiao.Name="李娇娇";
Proxy daili = new Proxy(jiaojiao);
daili.GiveDolls();
daili.GiveFlowers();
daili.GiveChocolate();
Console.Read();
}
戴励和李娇娇认识,这么调用是没错的。可是这样的话岂不是完全把Pursuit(追求者)给忽略了么?好像他根本不存在一样。
事实上,应该是Pursuit(追求者)通过Proxy(代理)送给SchoolGirl(被追求者)礼物,才是合理的。
版本三
代理借口如下:
interface IGiveGift{
void GiveDolls();
void GiveFlowers();
void GiveChocolate();
}
追求者类如下:
// 唯一变化就是让“追求者”去实现“送礼物”接口
class Pursuit :IGiveGift{
SchoolGirl mm;
public Pursuit(SchoolGirl mm){
this.mm=mm;
}
public void GiveDolls(){
Console.WriteLine(mm.Name + "送你洋娃娃");
}
public void GiveFlowers(){
Console.WriteLine(mm.Name + "送你鲜花");
}
public void GiveChocolate(){
Console.WriteLine(mm.Name + "送你巧克力");
}
}
代理类如下:
class Proxy : IGiiveGift{ // 让“代理”也去实现“送礼物”接口
Pursuit gg;
public Proxy(SchoolGirl mm){
gg= new Pursuit(mm);
}
// 在实现方法中去调用“追求者”类的相关方法
public void GiveDolls(){
gg.GiveDolls()
}
public void GiveFlowers(){
gg.GiveFlowers()
}
public void GiveChocolate(){
gg.GiveChocolate()
}
}
客户端如下:
static void Main(string[] args){
SchoolGirl jiaojiao = new SchoolGirl();
jiaojiao.Name="李娇娇";
Proxy daili = new Proxy(jiaojiao);
daili.GiveDolls();
daili.GiiveFlowers();
daili.GiveChocolaate();
Console.Read();
}
这样,娇娇虽然不认识追求她的人,但却可以通过代理人得到礼物。效果达到了。这就是——
代理模式
代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。
结构图:
Subject类,定义了RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方都可以使用Proxy。
abstract class Subject{
public abstract void Request();
}
RealSubject类,定义Proxy所代表的真实实体。
class RealSubject : Subject{
public override void Request(){
Console.WriteLine("真实的请求");
}
}
Proxy类,保存一个引用使得代理可以访问实体,并提供一个与Subject的接口相同的接口,这样代理就可以用来替代实体。
class Proxy :Subject{
RealSubject realSubject;
public override void Request(){
if(realSubject ==null){
realSubject=new RealSubject();
}
realSubject.Request();
}
}
客户端代码:
static void Main(string[] args){
Proxy proxy=new Proxy();
proxy.Request();
Console.Read();
}
代理模式一般用在什么场合呢?
第一,远程代理。也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。
第二,虚拟代理。是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。
第三,安全代理,用来控制真实对象访问时的权限。一般用于对象应该有不同的访问权限的时候。
第四,智能指引。是指当调用真实的对象时,代理处理另外一些事。
代理模式其实就是在访问对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。说白了,代理就是真实对象的代表。
本章完。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
本文是连载文章,此为第五章,学习为其他对象提供代理的代理模式。
上一章:https://blog.youkuaiyun.com/qq_36770641/article/details/82762763 装饰模式
下一章:https://blog.youkuaiyun.com/qq_36770641/article/details/82801288 工厂方法模式
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------