これは Martin の「Enterprise Application Architecture Patterns」から学んだもので、PHP 動的言語の特性を補助し、Java よりもはるかに簡単に遅延読み込み (LazyLoad) を実装できます。基本原則は、仮想プロキシ (仮想プロキシ) をプレースホルダとして使用することです。プロキシ オブジェクトのメンバー (メソッドまたは属性) にアクセスすると、読み込みがトリガーされます。
ただし、私が実装したバージョンには制限があります:
- オブジェクトにのみ適用可能で、配列などの基本的なデータ型をプロキシすることはできません (ArrayObject などの組み込みオブジェクトによってカプセル化する必要があります)
- プロキシされた後、ArrayAccess のインデクサーや Itreator のイテレーターなど、演算子オーバーロード プロパティを持つ一部のインターフェイス実装が無効になります。プロキシを使用してコレクション型の遅延読み込みを処理する場合、特別な Processed を行うためにサブクラスを継承する必要があります。 foreach を使用して外部で反復できるようにします
詳細については、私のブログを参照してください: http://tonyseek.tumblr.com/post/6166066775/virtual-proxy-lazy-load
- // テスト
- $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 はプロキシ オブジェクトのクロージャ関数を生成します
- */
- public function __construct(Closure $loader)
- {
- $this->loader = $loader;
- }
-
- /**
- * プロキシメンバーメソッドの呼び出し
- *
- * @param string $method
- * @param array $arguments
- * @throws BadMethodCallException
- * @returnmixed
- */
- 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
- * @returnmixed
- */
- public function __get($property)
- {
- $this->check();
-
- if (!isset($this->holder- >$property)) {
- throw new ErrorException();
- }
-
- return $this->holder->$property;
- }
-
- /**
- * プロキシメンバープロパティの割り当て
- *
- * @param string $property
- * @parammixed $value
- */
- public function __set($property , $value)
- {
- $this->check();
-
- $this->holder->$property = $value;
- }
-
- /**
- * プロキシオブジェクトが既に存在するかどうかを確認し、存在しない場合は生成します。
- */
- プライベート関数 check( )
- {
- if (null == $this->holder) {
- $loader = $this->loader;
- $this->holder = $loader();
- }
- }
- }
コードをコピー
|