概念

 

代理模式(Proxy)为其他对象提供一种代理以控制对这个对象的访问。使用代理模式创建代理对象,让代理对象控制目标对象的访问(目标对象可以是远程的对象、创建开销大的对象或需要安全控制的对象),并且可以在不改变目标对象的情况下添加一些额外的功能。

在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务。

经典例子就是网络代理,你想访问 Facebook 或者 Twitter ,如何绕过 GFW?找个代理网站。

 

示例


<?php

/**顶层接口
* Interface IGiveGift
*/
interface IGiveGift
{
function giveRose();
function giveChocolate();
}

/**追求者
* Class Follower
*/
class Follower implements IGiveGift
{
private $girlName;

function __construct($name='Girl')
{
$this->girlName=$name;
}

function giveRose()
{
echo "{$this->girlName}:这是我送你的玫瑰,望你能喜欢。<br/>";
}

function giveChocolate()
{
echo "{$this->girlName}:这是我送你的巧克力,望你能收下。<br/>";
}
}

/**代理
* Class Proxy
*/
class Proxy implements IGiveGift
{
private $follower;

function __construct($name='Girl')
{
$this->follower=new Follower($name);
}

function giveRose()
{
$this->follower->giveRose();
}

function giveChocolate()
{
$this->follower->giveChocolate();
}
}


$proxy=new Proxy('范冰冰');
$proxy->giveRose();
$proxy->giveChocolate();


 

 

优点  

       1、职责清晰

        真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。

        2、代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介和保护了目标对象的作用。

        3、高扩展性

       适用场景:

      1) 远程代理(Remote  Proxy)为一个位于不同的地址空间的对象提供一个本地的代理对象。

        这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又叫做大使(Ambassador)
      2) 虚拟代理(Virtual Proxy)根据需要创建开销很大的对象。

         如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。
      3) 保护代理(Protection Proxy)控制对原始对象的访问。

           保护代理用于对象应该有不同的访问权限的时候。
      4) 智能指引(Smart Reference)取代了简单的指针,它在访问对象时执行一些附加操作。
      5) Copy-on-Write代理:它是虚拟代理的一种,把复制(克隆)操作延迟到只有在客户端真正需要时才执行。

一般来说,对象的深克隆是一个开销较大的操作,Copy-on-Write代理可以让这个操作延迟,只有对象被用到的时候才被克隆。

 

总结

 

代理模式在很多情况下都非常有用,特别是你想强行控制一个对象的时候,比如延迟加载、监视状态变更的方法等等。

与类似接口的区别:

    适配器模式 —— 适配器模式为它所适配的对象提供了一个不同的接口,而代理提供了与它的实体相同的接口。
    装饰器模式 —— 两者目的不同:装饰器为对象添加一个或多个功能,而代理则控制对对象的访问。