이것은 Martin의 "Enterprise Application Architecture Patterns"에서 배운 내용입니다. PHP 동적 언어의 특성을 돕고 Java보다 훨씬 쉽게 지연 로딩(LazyLoad)을 구현할 수 있습니다. 기본 원칙은 가상 프록시(가상 프록시)를 자리 표시자로 사용하는 것입니다. 프록시 개체의 멤버(메서드 또는 속성)에 액세스하면 로딩이 트리거됩니다.
그러나 제가 구현한 버전에는 제한 사항이 있습니다.
은 객체에만 적용 가능하며 배열과 같은 기본 데이터 유형을 프록시할 수 없습니다(ArrayObject와 같은 내장 객체로 캡슐화해야 함)
가 프록시됩니다. 그 후 ArrayAccess의 인덱서 및 Itreator의 반복자와 같은 연산자 오버로딩 속성이 있는 일부 인터페이스 구현이 유효하지 않게 되었습니다. 이 프록시를 사용하여 컬렉션 유형의 지연 로드를 처리하는 경우 특수에 대한 하위 클래스를 상속해야 합니다. 외부 foreach 반복
demo
코드 복사 코드는 다음과 같습니다.
// Test
$v = new VirtualProxy(function(){
echo 'Now, Loading', "n";
$a = new ArrayObject(range(1,100));
$a->abc = 'a'
// 실제 사용에서는 DataMapper의 findXXX 메소드가 호출됩니다.
// 반환되는 것은 도메인 개체의 모음입니다
return $a;
})
// 이때 프록시 개체는 원본 개체로 직접 액세스됩니다
// , 생성자에 전달된 콜백 함수는
// 객체 작업 로드 지연을 달성하기 위해
echo $v->abc $v->offsetGet(50); 가상 프록시
코드 복사 코드는 다음과 같습니다.
/**
* 가상 프록시, 멤버에 접근할 때만 대상 객체를 생성하는 클로저 함수가 호출됩니다.
*
* @author tonyseek
*
*/
class VirtualProxy
{
private $holder = null
private $loader = null; ;
/**
* 가상 프록시, 멤버에 접근할 때만 대상 객체를 생성하는 클로저 함수가 호출됩니다.
*
* @param Closure $loader는 프록시 객체의 클로저 기능을 생성합니다
* /
공용 함수 __construct(Closure $loader)
{
$this->loader = $loader
}
/**
* 프록시 멤버 메서드 호출
*
* @param string $method
* @param array $arguments
* @throws BadMethodCallException
* @return 혼합
*/
공개 함수 __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 혼합
*/
공용 함수 __get($property)
{
$this- >check();
if ( !isset($this->holder->$property)) {
throw new ErrorException(); return $this->holder->$property; }
/**
* 프록시 구성원 속성 할당
*
* @param string $property
* @param 혼합 $value
*/
공용 함수 __set($property, $value)
{
$this->check();
$this->holder->$property = $value
}
/**
* 프록시 객체가 이미 존재하는지 확인하고, 존재하지 않으면 생성합니다.
*/
비공개 함수 check()
{
if (null == $this->holder) {
$loader = $this->loader
$this->holder = $로더()
}
}
}