PHP设计模式之代理模式的深入解析


Posted in PHP onJune 13, 2013

代理模式(Proxy),它是对简单处理程序(或指针)的增强,用于引用一个对象:这个指针被代理(Proxy)对象取代,代理对象位于客户端(Client)和真实执行程序之间,指针有一个可被多个目标利用的钩子。

从技术上讲,这种模式在客户端和真实主体(RealSubject)之间插入一个代理对象,维护subject接口和用不同的方式委派它的方法。代理可以透明地做任何事情:懒散创建RealSubject或载入数据,与其它机器交换消息,写时复制策略等。这与HTTP代理有点类似,其客户端(如浏览器)和应用程序依赖于与HTTP服务器的联系,代理在管理连接时可以完成其它任务,如访问控制和缓存大型下载文件。

PHP设计模式之代理模式的深入解析

代理模式的对象图与装饰模式对象图在结构上类似,但表达的目的各有不同,装饰者给对象动态增加行为,而代理则控制来自客户端的访问。此外,代理只在需要时才创建RealSubject。

参与者:
◆客户端(Client):取决于主体(Subject)实现;
◆主体(Subject):RealSubject的抽象;
◆真实主体(RealSubject):完成代价高昂的工作或包含大量的数据;
◆代理(Proxy):为Client提供一个与Subject一致的引用,仅在需要时才创建RealSubject实例或与RealSubject实例通信。

下面是两个被广泛使用的代理模式例子:
1、对象-关系映射(Orms)在运行中创建代理作为实体类的子类,以实现懒散加载(虚拟代理),这个代理会覆盖所有实体方法,在前面追加一个载入程序,在方法被真正调用前不会包含任何数据,Orms代理支持对象间的双向关系,不用加载整个数据库,因为它们被置于当前加载对象图的边界。

2、Java RMI使用远程代理对象(远程代理),当它们的方法被调用时,代理序列化参数,执行网络上的请求,委托调用另一个节点上的真实对象,这种技术允许透明地调用远程对象,不用担心它们是否在同一台机器上,但这种透明度很容易会使执行速度变慢。

下面的代码示例实现了一个ImageProxy,推迟了图像数据的加载。

/**  
 * Subject interface.  
 * Client depends only on this abstraction.  
 */ 
interface Image  
{  
    public function getWidth();      public function getHeight();  
    public function getPath();  
    /**  
     * @return string   the image's byte stream  
     */ 
    public function dump();  
}  
/**  
 * Abstract class to avoid repetition of boilerplate code in the Proxy  
 * and in the Subject. Only the methods which can be provided without  
 * instancing the RealSubject are present here.  
 */ 
abstract class AbstractImage implements Image  
{  
    protected $_width;  
    protected $_height;  
    protected $_path;  
    protected $_data;  
    public function getWidth()  
    {  
 return $this->_width;  
    }  
    public function getHeight()  
    {  
 return $this->_height;  
    }  
    public function getPath()  
    {  
 return $this->_path;  
    }  
}  
/**  
 * The RealSubject. Always loads the image, even if no dump of the data  
 * is required.  
 */ 
class RawImage extends AbstractImage  
{  
    public function __construct($path)  
    {  
 $this->_path = $path;  
 list ($this->_width, $this->_height) = getimagesize($path);  
 $this->_data = file_get_contents($path);  
    }  
    public function dump()  
    {  
 return $this->_data;  
    }  
}  
/**  
 * Proxy. Defers loading the image data until it becomes really mandatory.  
 * This class does its best to postpone the very expensive operations  
 * such as the actual loading of the BLOB.  
 */ 
class ImageProxy extends AbstractImage  
{  
    public function __construct($path)  
    {  
 $this->_path = $path;  
 list ($this->_width, $this->_height) = getimagesize($path);  
    }  
    /**  
     * Creates a RawImage and exploits its functionalities.  
     */ 
    protected function _lazyLoad()  
    {  
 if ($this->_realImage === null) {  
     $this->_realImage = new RawImage($this->_path);  
 }  
    }  
    public function dump()  
    {  
 $this->_lazyLoad();  
 return $this->_realImage->dump();  
    }  
}  
/**  
 * Client class that does not use the data dump of the image.  
 * Passing blindly a Proxy to this class and to other Clients makes sense  
 * as the data would be loaded anyway when Image::dump() is called.  
 */ 
class Client  
{  
    public function tag(Image $img)  
    {  
 return ';  
    }  
}  
$path = '/home/giorgio/shared/Immagini/kiki.png';  
$client = new Client();  
$image = new RawImage($path); // loading of the BLOB takes place  
echo $client->tag($image), "\n";  
$proxy = new ImageProxy($path);  
echo $client->tag($proxy), "\n"; // loading does not take place even here

以上代码实现了PHP的代理模式。简单来讲,代理模式就是为其他对象提供一个代理以控制对这个对象的访问。
PHP 相关文章推荐
一个查看session内容的函数
Oct 09 PHP
php数组函数序列 之shuffle()和array_rand() 随机函数使用介绍
Oct 29 PHP
关于zend studio 出现乱码问题的总结
Jun 23 PHP
wordpress自定义url参数实现路由功能的代码示例
Nov 28 PHP
php实现斐波那契数列的简单写法
Jul 19 PHP
ThinkPHP通过AJAX返回JSON的两种实现方法
Dec 18 PHP
PHP限制HTML内容中图片必须是本站的方法
Jun 16 PHP
帝国cms常用标签汇总
Jul 06 PHP
php数字每三位加逗号的功能函数
Oct 22 PHP
PHP使用SWOOLE扩展实现定时同步 MySQL 数据
Apr 09 PHP
ThinkPHP中Widget扩展的两种写法及调用方法详解
May 04 PHP
原生php实现excel文件读写的方法分析
Apr 25 PHP
PHP设计模式之责任链模式的深入解析
Jun 13 #PHP
PHP设计模式之结构模式的深入解析
Jun 13 #PHP
PHP设计模式之命令模式的深入解析
Jun 13 #PHP
深入Memcache的Session数据的多服务器共享详解
Jun 13 #PHP
探讨:如何使用PHP实现计算两个日期间隔的年、月、周、日数
Jun 13 #PHP
判断php数组是否为索引数组的实现方法
Jun 13 #PHP
深入解析yii权限分级式访问控制的实现(非RBAC法)
Jun 13 #PHP
You might like
PHP新手上路(三)
2006/10/09 PHP
PHP 将图片按创建时间进行分类存储的实现代码
2010/01/05 PHP
PHP实现动态web服务器方法
2015/07/29 PHP
ThinkPHP实现附件上传功能
2017/04/27 PHP
从父页面读取和操作iframe中内容方法
2009/07/25 Javascript
AJAX的跨域与JSONP(为文章自动添加短址的功能)
2010/01/17 Javascript
JavaScript使用IEEE 标准进行二进制浮点运算产生莫名错误的解决方法
2011/05/28 Javascript
JavaScript语言核心数据类型和变量使用介绍
2013/08/23 Javascript
jquery的each方法使用示例分享
2014/03/25 Javascript
js实现键盘Enter键提交表单的方法
2015/05/27 Javascript
Javascript使用post方法提交数据实例
2015/08/03 Javascript
jQuery右下角旋转环状菜单特效代码
2015/08/10 Javascript
详解Vue.js动态绑定class
2016/12/20 Javascript
浅谈JS如何实现真正的对象常量
2017/06/25 Javascript
使用ngrok+express解决本地环境中微信接口调试问题
2018/02/26 Javascript
angular4 JavaScript内存溢出问题
2018/03/06 Javascript
jQuery实现ajax回调函数带入参数的方法示例
2018/06/26 jQuery
利用js将ajax获取到的后台数据动态加载至网页中的方法
2018/08/08 Javascript
Node.js之readline模块的使用详解
2019/03/25 Javascript
微信小程序实现聊天室
2020/08/21 Javascript
[03:23:49]2016.12.17日完美“圣”典全回顾
2016/12/19 DOTA
详解python进行mp3格式判断
2016/12/23 Python
python dict 相同key 合并value的实例
2019/01/21 Python
Django对接支付宝实现支付宝充值金币功能示例
2019/12/17 Python
Python3 A*寻路算法实现方式
2019/12/24 Python
详解python 降级到3.6终极解决方案
2020/02/06 Python
如何导出python安装的所有模块名称和版本号到文件中
2020/06/05 Python
详解用Python调用百度地图正/逆地理编码API
2020/07/02 Python
PyCharm配置anaconda环境的步骤详解
2020/07/31 Python
python 多线程爬取壁纸网站的示例
2021/02/20 Python
新护士岗前培训制度
2014/02/02 职场文书
2015年销售人员工作总结
2015/04/07 职场文书
新郎父母婚礼致辞
2015/07/27 职场文书
总结python多进程multiprocessing的相关知识
2021/06/29 Python
Java8中接口的新特性使用指南
2021/11/01 Java/Android
js 数组 fill() 填充方法
2021/11/02 Javascript