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 5.0对象模型深度探索之对象复制
Mar 27 PHP
用PHP查询搜索引擎排名位置的代码
Jan 05 PHP
PHP中uploaded_files函数使用方法详解
Mar 09 PHP
php中使用Imagick实现图像直方图的实现代码
Aug 30 PHP
怎样给PHP源代码加密?PHP二进制加密与解密的解决办法
Apr 22 PHP
WIN8.1下搭建PHP5.6环境
Apr 29 PHP
Session 失效的原因汇总及解决丢失办法
Sep 30 PHP
thinkphp 抓取网站的内容并且保存到本地的实例详解
Aug 25 PHP
yii2.0整合阿里云oss的示例代码
Sep 19 PHP
如何优雅的使用 laravel 的 validator验证方法
Nov 11 PHP
Laravel框架实现的上传图片到七牛功能详解
Sep 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
Laravel框架Request、Response及Session操作示例
2019/05/06 PHP
Js+Jq获取URL参数的集中方法示例代码
2014/05/20 Javascript
JavaScript声明变量时为什么要加var关键字
2014/09/29 Javascript
javascript中的Function.prototye.bind
2015/06/25 Javascript
JS+CSS实现的简单折叠展开多级菜单效果
2015/09/12 Javascript
jQuery实现网页顶部固定导航效果代码
2015/12/24 Javascript
基于Javascript实现文件实时加载进度的方法
2016/10/12 Javascript
node.js实现微信JS-API封装接口的示例代码
2017/09/06 Javascript
详解如何实现一个简单的 vuex
2018/02/10 Javascript
Vue自定义指令实现checkbox全选功能的方法
2018/02/28 Javascript
解决layui动态加载复选框无法选中的问题
2019/09/20 Javascript
基于纯JS实现多张图片的懒加载Lazy过程解析
2019/10/14 Javascript
在VUE中实现文件下载并判断状态的方法
2019/11/08 Javascript
如何基于layui的laytpl实现数据绑定的示例代码
2020/04/10 Javascript
Vue单页面应用中实现Markdown渲染
2021/02/14 Vue.js
[01:14:34]DOTA2上海特级锦标赛C组资格赛#2 LGD VS Newbee第一局
2016/02/28 DOTA
python线程锁(thread)学习示例
2013/12/04 Python
python机器学习理论与实战(四)逻辑回归
2018/01/19 Python
python如何读写csv数据
2018/03/21 Python
Python 中导入csv数据的三种方法
2018/11/01 Python
Python实现将通信达.day文件读取为DataFrame
2018/12/22 Python
利用Python实现Shp格式向GeoJSON的转换方法
2019/07/09 Python
Python爬取视频(其实是一篇福利)过程解析
2019/08/01 Python
Python列表删除元素del、pop()和remove()的区别小结
2019/09/11 Python
Python Lambda函数使用总结详解
2019/12/11 Python
python基于event实现线程间通信控制
2020/01/13 Python
翻转数列python实现,求前n项和,并能输出整个数列的案例
2020/05/03 Python
python实现学生信息管理系统源码
2021/02/22 Python
CSS3 filter(滤镜)实现网页灰色或者黑色模式的代码
2020/11/30 HTML / CSS
惠而浦美国官网:Whirlpool.com
2021/01/19 全球购物
安全生产月标语
2014/10/07 职场文书
群众路线剖析材料怎么写
2014/10/09 职场文书
教师节获奖感言
2015/07/31 职场文书
幼儿园小班教育随笔
2015/08/14 职场文书
远程教育学习心得体会
2016/01/23 职场文书
基于python制作简易版学生信息管理系统
2021/04/20 Python