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 相关文章推荐
不用iconv库的gb2312与utf-8的互换函数
Oct 09 PHP
简单的用PHP编写的导航条程序
Oct 09 PHP
PHP Token(令牌)设计
Mar 15 PHP
MayFish PHP的MVC架构的开发框架
Aug 13 PHP
php 用checkbox一次性删除多条记录的方法
Feb 23 PHP
php导出word文档与excel电子表格的简单示例代码
Mar 08 PHP
PHP开启opcache提升代码性能
Apr 26 PHP
php版微信公众平台开发之验证步骤实例详解
Sep 23 PHP
php 提交表单 关闭layer弹窗iframe的实例讲解
Aug 20 PHP
PHP获取MySQL执行sql语句的查询时间方法
Aug 21 PHP
PHP5.6读写excel表格文件操作示例
Feb 26 PHP
PHP正则之正向预查与反向预查讲解与实例
Apr 06 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
风味层面去分析咖啡油脂
2021/03/03 咖啡文化
php 获取本地IP代码
2013/06/23 PHP
PHP图片处理之图片背景、画布操作
2014/11/19 PHP
PHP连接SQL Server的方法分析【基于thinkPHP5.1框架】
2019/05/06 PHP
Laravel 登录后清空COOKIE的操作方法
2019/10/14 PHP
php实现的证件照换底色功能示例【人像抠图/换背景图】
2020/05/29 PHP
Javascript 读后台cookie代码
2008/09/15 Javascript
flash 得到自身url参数的代码
2009/11/15 Javascript
jQuery下的几个你可能没用过的功能
2010/08/29 Javascript
jquery和javascript的区别(常用方法比较)
2013/07/04 Javascript
JavaScript中访问节点对象的方法有哪些如何使用
2013/09/24 Javascript
比较不错的JS/JQuery显示或隐藏文本的方法
2014/02/13 Javascript
nodejs之请求路由概述
2014/07/05 NodeJs
轻松创建nodejs服务器(9):实现非阻塞操作
2014/12/18 NodeJs
使用node.js中的Buffer类处理二进制数据的方法
2016/11/26 Javascript
用原生js做单页应用
2017/01/17 Javascript
bootstrap警告框示例代码分享
2017/05/17 Javascript
react.js使用webpack搭配环境的入门教程
2017/08/14 Javascript
javascript实现获取一个日期段内每天不同的价格(计算入住总价格)
2018/02/05 Javascript
vue 中filter的多种用法
2018/04/26 Javascript
解决vue热替换失效的根本原因
2018/09/19 Javascript
VUE 实现动态给对象增加属性,并触发视图更新操作示例
2019/11/29 Javascript
前端深入理解Typescript泛型概念
2020/03/09 Javascript
Python修改Excel数据的实例代码
2013/11/01 Python
对python中的float除法和整除法的实例详解
2019/07/20 Python
python 列表、字典和集合的添加和删除操作
2019/12/16 Python
python之MSE、MAE、RMSE的使用
2020/02/24 Python
vscode配置anaconda3的方法步骤
2020/08/08 Python
Bootstrap 学习分享
2012/11/12 HTML / CSS
美国第二大连锁书店:Books-A-Million
2017/12/28 全球购物
Yahoo-PHP面试题1
2016/07/20 面试题
高中自我评价分享
2013/12/05 职场文书
行政专员工作职责
2013/12/22 职场文书
最新会计专业求职信范文
2014/01/28 职场文书
Python爬虫之用Xpath获取关键标签实现自动评论盖楼抽奖(二)
2021/06/07 Python
mybatis 获取无数据的字段不显示的问题
2021/07/15 Java/Android