设计模式(五)代理模式

一个男生卓贾易追求一个女生李娇娇,两人并不认识,但两人有共同的好友戴励。代码如何写?

版本一

最开始很容易想到——

结构图: 

追求者类:

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  工厂方法模式

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值