找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 982|回复: 0
打印 上一主题 下一主题

PHP中使用虚代理实现延迟加载技术

[复制链接]

2588

主题

2588

帖子

7694

积分

论坛元老

Rank: 8Rank: 8

积分
7694
跳转到指定楼层
楼主
发表于 2018-2-14 05:53:16 | 只看该作者 回帖奖励 |正序浏览 |阅读模式

            话说这货是从 Martin 大神的《企业应用架构模式》中学到的,辅助 PHP 动态语言的特性,可以比 Java 轻松很多的实现延迟加载——通过一个虚代理占位符。唯一的缺陷,是只能代理对象,不能代理内置基本类型。
我试水的 PHP 领域模型设计中,也是用这个来实现 DomainObject 的延迟加载。
[U]复制代码[/U] 代码如下:
* 虚代理,只有在被访问成员时才调用闭包函数生成目标对象。
*
* @author tonyseek
*
*/
class VirtualProxy
{
    private $holder = null;
    private $loader = null;
    /**
     * 虚代理,只有在被访问成员时才调用闭包函数生成目标对象。
     *
     * @param Closure $loader 生成被代理对象的闭包函数
     */
    public function __construct(Closure $loader)
    {
            $this->loader = $loader;
    }
    /**
     * 代理成员方法的调用
     *
     * @param string $method
     * @param array  $arguments
     * @throws BadMethodCallException
     * @return mixed
     */
    public function __call($method, array $arguments = null)
    {
            $this->check();
            if (!method_exists($this->holder, $method)) {
                    throw new BadMethodCallException();
            }
            return call_user_func_array(
                    array(&$this->holder, $method),
                    $arguments);
    }
    /**
     * 代理成员属性的读取
     *
     * @param string $property
     * @throws ErrorException
     * @return mixed
     */
    public function __get($property)
    {
            $this->check();
            if (!isset($this->holder->$property)) {
                    throw new ErrorException();
            }
            return $this->holder->$property;
    }
    /**
     * 代理成员属性的赋值
     *
     * @param string $property
     * @param mixed  $value
     */
    public function __set($property, $value)
    {
            $this->check();
            $this->holder->$property = $value;
    }
    /**
     * 检查是否已经存在被代理对象,不存在则生成。
     */
    private function check()
    {
            if (null == $this->holder) {
                    $loader = $this->loader;
                    $this->holder = $loader();
            }
    }
}
// 测试
$v = new VirtualProxy(function(){
        echo 'Now, Loading', "\n";
    $a = new ArrayObject(range(1,100));
    $a->abc = 'a';
        // 实际使用中,这里调用的是 DataMapper 的 findXXX 方法
        // 返回的是领域对象集合
    return $a;
});
// 代理对象直接当作原对象访问
// 而此时构造方法传入的 callback 函数才被调用
// 从而实现加载对象操作的延迟
echo $v->abc . $v->offsetGet(50);
            
            
您可能感兴趣的文章:
  • 说说PHP的autoLoad自动加载机制
  • php自动加载机制的深入分析
  • 解析php类的注册与自动加载
  • php自动加载autoload机制示例分享
  • php ci框架中加载css和js文件失败的原因及解决方法
  • PHP管理依赖(dependency)关系工具 Composer的自动加载(autoload)
  • php广告加载类用法实例
  • php绘图之加载外部图片的方法
  • PHP实现懒加载的方法
            
  • 分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    用户反馈
    客户端