これは Martin の「Enterprise Application Architecture Patterns」から学んだもので、PHP 動的言語の特性を補助し、Java よりもはるかに簡単に遅延読み込み (LazyLoad) を実装できます。基本原則は、仮想プロキシ (仮想プロキシ) をプレースホルダとして使用することです。プロキシ オブジェクトのメンバー (メソッドまたは属性) にアクセスすると、読み込みがトリガーされます。
ただし、私が実装したバージョンには制限があります:
オブジェクトにのみ適用可能で、配列などの基本的なデータ型をプロキシすることはできません (ArrayObject などの組み込みオブジェクトでカプセル化する必要があります)
プロキシされた後、一部のインターフェイスプロパティをオーバーロードする演算子を使用すると、ArrayAccess のインデクサーや Itreator のイテレーターなどの実装が無効になります。このプロキシを使用してコレクション型の遅延読み込みを処理する場合は、外部の foreach 反復を処理できるように、特別な処理用のサブクラスを継承する必要があります。使用した
デモ
コードをコピー コードは次のようになります:
// テスト
$v = new VirtualProxy(function(){
echo 'Now, Loading', "n";
$a = new ArrayObject(range(1,100));
$a->abc = 'a';
// 実際の使用では、DataMapper の findXXX メソッドが呼び出されます
// 返されるのはドメイン オブジェクトのコレクションです
return $a}); / プロキシ オブジェクトは元のオブジェクトとして直接アクセスされます
/ / このとき、コンストラクターで渡されるコールバック関数が呼び出されます
// オブジェクトの読み込みの遅延を実現するための操作
echo $v->abc 。 ->offsetGet(50);
仮想プロキシ
コードをコピーします。 コードは次のとおりです。
/**
* 仮想プロキシ。メンバーにアクセスされた場合にのみクロージャ関数が呼び出され、ターゲット オブジェクトが生成されます。
*
* @著者tonyseek
*
*/
class VirtualProxy
{
private $holder = null;
/**
* 仮想プロキシ。メンバーにアクセスされた場合にのみクロージャー関数が呼び出され、ターゲット オブジェクトが生成されます。
*
* @param Closure $loader プロキシ オブジェクトのクロージャ関数を生成します
*/
パブリック関数 __construct(Closure $loader)
{
$this->loader = $loader;
}
/**
* プロキシ メンバー メソッドの呼び出し
*
* @param string $method
* @param array $arguments
* @throws BadMethodCallException
* @returnmixed
*/
パブリック関数 __call($method 、配列 $arguments = null)
{
$this->check() ;
if (!method_exists($this->holder, $method)) {
新しい BadMethodCallException() をスローします
return; call_user_func_array(
array(&$this->holder, $method),
$arguments);
/**
* プロキシ メンバー プロパティの読み取り
*
* @param string $property
* @throws ErrorException
* @returnmixed
*/
public function __get($property)
{
$this-> check();
if (!isset($this->holder->$property)) {
新しい ErrorException();
return $this->holder->$property; }
/**
* プロキシメンバープロパティの割り当て
*
* @param string $property
* @parammixed $value
*/
パブリック関数 __set($property , $value)
{
$this->check();
$this->holder->$property = $value ;
}
/**
* プロキシ オブジェクトが既に存在するかどうかを確認し、存在しない場合は生成します。
*/
プライベート関数 check( )
{
if (null == $this->holder) {
$loader = $this->loader; >ホルダー = $loader()
}
}
}