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相关资料
Oct 09 PHP
PHP下利用shell后台运行PHP脚本,并获取该脚本的Process ID的代码
Sep 19 PHP
PHP输出数组中重名的元素的几种处理方法
Sep 05 PHP
PHP仿博客园 个人博客(2) 数据库增添改删
Jul 05 PHP
PHP中mysql_field_type()函数用法
Nov 24 PHP
php rsa加密解密使用详解
Jan 14 PHP
php生成图片验证码
Jun 09 PHP
详解WordPress中调用评论模板和循环输出评论的PHP函数
Jan 05 PHP
PHP中的正则表达式实例详解
Apr 25 PHP
jQuery ajax+PHP实现的级联下拉列表框功能示例
Feb 12 PHP
Laravel 6 将新增为指定队列任务设置中间件的功能
Aug 06 PHP
laravel 操作数据库常用函数的返回值方法
Oct 11 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
一个简单的域名注册情况查询程序
2006/10/09 PHP
php的闭包(Closure)匿名函数初探
2016/02/14 PHP
Ajax中的JSON格式与php传输过程全面解析
2017/11/14 PHP
PHP连续签到功能实现方法详解
2019/12/04 PHP
Prototype 1.5.0_rc1 及 Prototype 1.5.0 Pre0小抄本
2006/09/22 Javascript
javascript 基础篇1 什么是js 建立第一个js程序
2012/03/14 Javascript
js+xml生成级联下拉框代码
2012/07/24 Javascript
JS+CSS实现Div弹出窗口同时背景变暗的方法
2015/03/04 Javascript
javascript中日期函数new Date()的浏览器兼容性问题
2015/09/05 Javascript
适用于手机端的jQuery图片滑块动画
2016/12/09 Javascript
JavaScript评论点赞功能的实现方法
2017/03/13 Javascript
浅析vue-router jquery和params传参(接收参数)$router $route的区别
2018/08/03 jQuery
在 Angular6 中使用 HTTP 请求服务端数据的步骤详解
2018/08/06 Javascript
elementUI select组件默认选中效果实现的方法
2019/03/25 Javascript
React-redux实现小案例(todolist)的过程
2019/09/29 Javascript
解决ele ui 表格表头太长问题的实现
2019/11/13 Javascript
Vue基于iview实现登录密码的显示与隐藏功能
2020/03/06 Javascript
解决Python字典写入文件出行首行有空格的问题
2017/09/27 Python
关于Python 的简单栅格图像边界提取方法
2019/07/05 Python
python re.sub()替换正则的匹配内容方法
2019/07/22 Python
如何通过安装HomeBrew来安装Python3
2020/12/23 Python
python FTP编程基础入门
2021/02/27 Python
CSS3 :default伪类选择器使用简介
2018/03/15 HTML / CSS
HTML5中外部浏览器唤起微信分享功能的代码
2020/09/15 HTML / CSS
什么是smarty? Smarty的优点是什么?
2013/08/11 面试题
酒店管理专业毕业生求职自荐信
2014/04/28 职场文书
创先争优标语
2014/06/27 职场文书
销售团队获奖感言
2014/08/14 职场文书
财政专业大学生职业生涯规划书
2014/09/17 职场文书
学生评语集锦
2015/01/04 职场文书
宣传稿格式范文
2015/07/23 职场文书
感恩父母主题班会
2015/08/12 职场文书
公司年会晚会开幕词
2019/04/02 职场文书
go语言中json数据的读取和写出操作
2021/04/28 Golang
css display table 自适应高度、宽度问题的解决
2021/05/07 HTML / CSS
MySQL中TIMESTAMP类型返回日期时间数据中带有T的解决
2022/12/24 MySQL