PHP中使用虚代理实现延迟加载技术
话说这货是从Martin大神的《企业应用架构模式》中学到的,辅助PHP动态语言的特性,可以比Java轻松很多的实现延迟加载——通过一个虚代理占位符。唯一的缺陷,是只能代理对象,不能代理内置基本类型。
我试水的PHP领域模型设计中,也是用这个来实现DomainObject的延迟加载。
*虚代理,只有在被访问成员时才调用闭包函数生成目标对象。 * *@authortonyseek * */ classVirtualProxy { private$holder=null; private$loader=null;
/** *虚代理,只有在被访问成员时才调用闭包函数生成目标对象。 * *@paramClosure$loader生成被代理对象的闭包函数 */ publicfunction__construct(Closure$loader) { $this->loader=$loader; }
/** *代理成员方法的调用 * *@paramstring$method *@paramarray $arguments *@throwsBadMethodCallException *@returnmixed */ publicfunction__call($method,array$arguments=null) { $this->check();
if(!method_exists($this->holder,$method)){ thrownewBadMethodCallException(); }
returncall_user_func_array( array(&$this->holder,$method), $arguments); }
/** *代理成员属性的读取 * *@paramstring$property *@throwsErrorException *@returnmixed */ publicfunction__get($property) { $this->check();
if(!isset($this->holder->$property)){ thrownewErrorException(); }
return$this->holder->$property; }
/** *代理成员属性的赋值 * *@paramstring$property *@parammixed $value */ publicfunction__set($property,$value) { $this->check();
$this->holder->$property=$value; }
/** *检查是否已经存在被代理对象,不存在则生成。 */ privatefunctioncheck() { if(null==$this->holder){ $loader=$this->loader; $this->holder=$loader(); } } }
//测试 $v=newVirtualProxy(function(){ echo'Now,Loading',"\n"; $a=newArrayObject(range(1,100)); $a->abc='a'; //实际使用中,这里调用的是DataMapper的findXXX方法 //返回的是领域对象集合 return$a; }); //代理对象直接当作原对象访问 //而此时构造方法传入的callback函数才被调用 //从而实现加载对象操作的延迟 echo$v->abc.$v->offsetGet(50);