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 相关文章推荐
针对初学PHP者的疑难问答(2)
Oct 09 PHP
超强分页类2.0发布,支持自定义风格,默认4种显示模式
Jan 02 PHP
PHP日期时间函数的高级应用技巧
May 16 PHP
PHP 远程文件管理,可以给表格排序,遍历目录,时间排序
Aug 07 PHP
PHP数组传递是值传递而非引用传递概念纠正
Jan 31 PHP
yii框架通过控制台命令创建定时任务示例
Apr 30 PHP
ThinkPHP查询中的魔术方法简述
Jun 25 PHP
PHP制作图形验证码代码分享
Oct 23 PHP
浅谈PDO的rowCount函数
Jun 18 PHP
php使用ffmpeg获取视频信息并截图的实现方法
May 03 PHP
Windows平台实现PHP连接SQL Server2008的方法
Jul 26 PHP
thinkPHP+LayUI 流加载实现功能
Sep 27 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+mysql分页代码详解
2008/03/27 PHP
用PHP程序实现支持页面后退的两种方法
2008/06/30 PHP
PHP序列化/对象注入漏洞分析
2016/04/18 PHP
php curl 模拟登录并获取数据实例详解
2016/12/22 PHP
yii框架无限极分类的实现方法
2017/04/08 PHP
PHP异常处理定义与使用方法分析
2017/07/25 PHP
PHP实现找出有序数组中绝对值最小的数算法分析
2017/08/07 PHP
JavaScript 基础问答三
2008/12/03 Javascript
基于jquery的从一个页面跳转到另一个页面的指定位置的实现代码(带平滑移动的效果)
2011/05/24 Javascript
基于JQuery模仿苹果桌面的Dock效果(初级版)
2012/10/15 Javascript
简单几行JS Code实现IE邮件转发新浪微博
2013/07/03 Javascript
javascript禁用键盘功能键让右击及其他键无效
2013/10/09 Javascript
类似php的js数组的in_array函数自定义方法
2013/12/27 Javascript
jQuery.extend 函数及用法详细
2015/09/06 Javascript
javascript实现任务栏消息提示的简单实例
2016/05/31 Javascript
javascript中的面向对象
2017/03/30 Javascript
Vue.js实现的购物车功能详解
2019/01/27 Javascript
js 实现ajax发送步骤过程详解
2019/07/25 Javascript
[01:14:05]《加油DOTA》第四期
2014/08/25 DOTA
[03:41]DOTA2上海特锦赛小组赛第三日recap精彩回顾
2016/02/28 DOTA
[56:38]DOTA2-DPC中国联赛正赛Aster vs Magma BO3 第一场 3月5日
2021/03/11 DOTA
python基于xmlrpc实现二进制文件传输的方法
2015/06/02 Python
Python中subprocess的简单使用示例
2015/07/28 Python
python如何实现视频转代码视频
2019/06/17 Python
python利用dlib获取人脸的68个landmark
2019/11/27 Python
Python基础之列表常见操作经典实例详解
2020/02/26 Python
个人教师自我评价范文
2013/12/02 职场文书
法律进学校实施方案
2014/03/15 职场文书
我的中国梦演讲稿800字
2014/08/19 职场文书
学校领导干部民主生活会整改方案
2014/09/29 职场文书
综治工作汇报材料
2014/10/27 职场文书
2014年安全员工作总结
2014/11/13 职场文书
现实表现证明材料
2015/06/19 职场文书
优秀乡村医生事迹材料(2016精选版)
2016/02/29 职场文书
Python编程根据字典列表相同键的值进行合并
2021/10/05 Python
MySQL读取JSON转换的方式
2022/03/18 MySQL