ホームページ  >  記事  >  バックエンド開発  >  仮想プロキシは遅延読み込みを実装します

仮想プロキシは遅延読み込みを実装します

WBOY
WBOYオリジナル
2016-07-25 09:09:57949ブラウズ

これは Martin の「Enterprise Application Architecture Patterns」から学んだもので、PHP 動的言語の特性を補助し、Java よりもはるかに簡単に遅延読み込み (LazyLoad) を実装できます。基本原則は、仮想プロキシ (仮想プロキシ) をプレースホルダとして使用することです。プロキシ オブジェクトのメンバー (メソッドまたは属性) にアクセスすると、読み込みがトリガーされます。

ただし、私が実装したバージョンには制限があります:

  1. オブジェクトにのみ適用可能で、配列などの基本的なデータ型をプロキシすることはできません (ArrayObject などの組み込みオブジェクトによってカプセル化する必要があります)
  2. プロキシされた後、ArrayAccess のインデクサーや Itreator のイテレーターなど、演算子オーバーロード プロパティを持つ一部のインターフェイス実装が無効になります。プロキシを使用してコレクション型の遅延読み込みを処理する場合、特別な Processed を行うためにサブクラスを継承する必要があります。 foreach を使用して外部で反復できるようにします

詳細については、私のブログを参照してください: http://tonyseek.tumblr.com/post/6166066775/virtual-proxy-lazy-load

  1. // テスト
  2. $v = new VirtualProxy(function(){
  3. echo 'Now, Loading', "n";
  4. $a = new ArrayObject(range(1,100));
  5. $a->abc = 'a';
  6. //実際の使用では、ここでDataMapperのfindXXXメソッドを呼び出します
  7. //返されるのはドメインオブジェクトのコレクションです
  8. return $a;
  9. });
  10. //プロキシオブジェクトに直接アクセスします元のオブジェクトとして
  11. // このとき、コンストラクターによって渡されたコールバック関数が呼び出されます
  12. // オブジェクトのロード操作の遅延を実現するため
  13. echo $v->abc . $v->offsetGet(50) ;
コードをコピー
  1. /**
  2. * 仮想プロキシ、クロージャ関数はメンバーにアクセスされたときにのみ呼び出され、ターゲット オブジェクトを生成します。
  3. *
  4. * @author tonyseek
  5. *
  6. */
  7. class VirtualProxy
  8. {
  9. private $holder = null;
  10. private $loader = null;
  11. /**
  12. * 仮想プロキシ、クロージャ関数はメンバーにアクセスされたときにのみ呼び出され、ターゲット オブジェクトを生成します。
  13. *
  14. * @param Closure $loader はプロキシ オブジェクトのクロージャ関数を生成します
  15. */
  16. public function __construct(Closure $loader)
  17. {
  18. $this->loader = $loader;
  19. }
  20. /**
  21. * プロキシメンバーメソッドの呼び出し
  22. *
  23. * @param string $method
  24. * @param array $arguments
  25. * @throws BadMethodCallException
  26. * @returnmixed
  27. */
  28. public function __call($method, array $arguments = null)
  29. {
  30. $this->check() ;
  31. if (!method_exists($this->holder, $method)) {
  32. throw new BadMethodCallException();
  33. }
  34. return call_user_func_array(
  35. array(&$this->holder, $method),
  36. $arguments);
  37. }
  38. /**
  39. * プロキシメンバープロパティの読み取り
  40. *
  41. * @param string $property
  42. * @throws ErrorException
  43. * @returnmixed
  44. */
  45. public function __get($property)
  46. {
  47. $this->check();
  48. if (!isset($this->holder- >$property)) {
  49. throw new ErrorException();
  50. }
  51. return $this->holder->$property;
  52. }
  53. /**
  54. * プロキシメンバープロパティの割り当て
  55. *
  56. * @param string $property
  57. * @parammixed $value
  58. */
  59. public function __set($property , $value)
  60. {
  61. $this->check();
  62. $this->holder->$property = $value;
  63. }
  64. /**
  65. * プロキシオブジェクトが既に存在するかどうかを確認し、存在しない場合は生成します。
  66. */
  67. プライベート関数 check( )
  68. {
  69. if (null == $this->holder) {
  70. $loader = $this->loader;
  71. $this->holder = $loader();
  72. }
  73. }
  74. }
コードをコピー


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。