コアポイント
仮想プロキシは、費用のかかるタスクの実行を遅らせるための効果的なツール(たとえば、ストレージ層の大量のデータの読み込みを遅らせる)、およびオブジェクト指向のアプリケーションでの一般的な剛性と脆弱性の問題を軽減するための効果的なツールです。
仮想エージェントの名前は派手に聞こえますが、おそらく、単なる退屈な独断的原理以上の「インターフェイス指向プログラミング」の概念の最も顕著な例の1つです。仮想プロキシは、単純な方法で実装された一時的な多型ではなく、動的な多型)に基づいており、クライアントコードを変更せずに費用のかかるオブジェクトグラフの構築/読み込みを遅らせることができるシンプルで信頼できる概念です。エージェントの大きな利点は、単一のオブジェクトまたはオブジェクトのコレクションを使用するように概念的に設計できることです(またはその両方が、懸念の分離を危険にさらす可能性があり、時間の経過とともに管理が困難です)。実用的な観点から、仮想プロキシによって提供される機能をどのように活用するかを実証するために、このシリーズの最初の部分で、基本プロキシを使用して単純なドメインモデルを満たすためにデータベースから集計を抽出する方法を示すいくつかの開発プロセスを紹介します。経験は有益であり、幸いなことに楽しいことですが、それの反対側は仮想エージェントの内と外を示すので少し欺cept的ですが、より現実的なシナリオでそれらを実装する方法を示していません。このプロキシは、レイジーロードストレージ内のドメインオブジェクトの収集という点で比類のないものです。この概念を理解するには、ブログ投稿のバッチを検討してください。関連するコメントの各セットをオンデマンドでデータベースから抽出できます。通常、練習は最高の教師です。このセクションでは、プロキシをドメイン固有のオブジェクトのコレクションに接続する方法を示します。この典型的なシナリオを非常に基本的なレベルで再現して、その運転ロジックを簡単に理解できるようにします。
レルムオブジェクトのコレクションを作成前述のように、前述のように、仮想エージェントは通常、永続レイヤーから基礎となるレルムオブジェクトコレクションに結合した集計根を取得するときに作成されます。コレクションの性質により、多くの場合、コレクションの事前設定は高価であるため、データベースの往復のオーバーヘッドを削減するためにオンデマンドでロードするのに適した候補になります。さらに、ブログ投稿とそれに対応するコメントとの間の「1対多」の関係がこのユースケースに非常に忠実に反映されていることを考えると、特定のエージェントを扱う前に、いくつかの単純なドメインクラスを通じて関係を最初にモデル化することは有益です。物事を理解しやすくするために、テスト段階で追加する2人の参加者は、孤立したインターフェイスと基本的な実装者になります。これらの2つは、一般的なブログ投稿オブジェクトの契約と実装を定義するために組み合わせています:
<?php namespace Model; use ModelCollectionCommentCollectionInterface; interface PostInterface { public function setId($id); public function getId(); public function setTitle($title); public function getTitle(); public function setContent($content); public function getContent(); public function setComments(CommentCollectionInterface $comments); public function getComments(); }
<?php namespace Model; use ModelCollectionCommentCollectionInterface; class Post implements PostInterface { protected $id; protected $title; protected $content; protected $comments; public function __construct($title, $content, CommentCollectionInterface $comments = null) { $this->setTitle($title); $this->setContent($content); $this->comments = $comments; } // ... (Post class methods remain largely unchanged) ... }
<?php namespace Model; interface CommentInterface { public function setId($id); public function getId(); public function setContent($content); public function getContent(); public function setPoster($poster); public function getPoster(); }
<?php namespace Model; class Comment implements CommentInterface { protected $id; protected $content; protected $poster; public function __construct($content, $poster) { $this->setContent($content); $this->setPoster($poster); } // ... (Comment class methods remain largely unchanged) ... }
<?php namespace ModelCollection; interface CommentCollectionInterface extends Countable, IteratorAggregate { public function getComments(); }
<?php namespace ModelCollection; use ModelCommentInterface; class CommentCollection implements CommentCollectionInterface { protected $comments = array(); public function __construct(array $comments = array()) { // ... (CommentCollection class methods remain largely unchanged) ... } }
仮想エージェントを介したドメインオブジェクトのコレクションとの相互作用率直に言って、前述のように、ラッピングアレイのコレクションは、他の依存関係に頼らずに独立して存在する可能性があります。 (懐疑的な場合は、教義のコレクションが舞台裏でどのように機能するかを自由に確認してください。)それでも、実際のレビューコレクションの動作をシミュレートするプロキシを実装しようとしていることを忘れないでください。尋ねられるべき質問は、データベースからコメントを抽出し、以前のコレクションにどのように抽出するのですか?これを達成するにはいくつかの方法がありますが、最も魅力的なものは、持続性の無関係を改善するため、データマッパーを使用することだと思います。以下のマッパーは、ストレージからコメントのコレクションを取得するのを嬉しく思います。確認してください:
<?php namespace Model; use ModelCollectionCommentCollectionInterface; interface PostInterface { public function setId($id); public function getId(); public function setTitle($title); public function getTitle(); public function setContent($content); public function getContent(); public function setComments(CommentCollectionInterface $comments); public function getComments(); }
<?php namespace Model; use ModelCollectionCommentCollectionInterface; class Post implements PostInterface { protected $id; protected $title; protected $content; protected $comments; public function __construct($title, $content, CommentCollectionInterface $comments = null) { $this->setTitle($title); $this->setContent($content); $this->comments = $comments; } // ... (Post class methods remain largely unchanged) ... }
ご想像のとおり、CommentCollectionProxyは、実際のコメントのコレクションと同じインターフェイスを実装します。ただし、そのgetComments()メソッドは、実際の作業を舞台裏で行い、コンストラクターに渡されたマッパーを介してデータベースからのコメントの負荷を遅らせます。このシンプルで効果的な方法では、過剰に仕入れなくても、コメントに対してあらゆる種類の巧妙なアクションを実行できます。どのような方法を見たいですか?データベースからの特定のブログ投稿にすべてのコメントを縛る必要があるとします。次のコードスニペットはこれを行うことができます:
<?php namespace Model; interface CommentInterface { public function setId($id); public function getId(); public function setContent($content); public function getContent(); public function setPoster($poster); public function getPoster(); }
このアプローチの欠点は、コメントが最初にストレージから抽出され、次にポストオブジェクトの内側に注入されることです。逆の方法でそれを行う方法ですが、今回はクライアントコードをプロキシで「スプーフィング」することですか?
<?php namespace Model; class Comment implements CommentInterface { protected $id; protected $content; protected $poster; public function __construct($content, $poster) { $this->setContent($content); $this->setPoster($poster); } // ... (Comment class methods remain largely unchanged) ... }
<?php namespace ModelCollection; interface CommentCollectionInterface extends Countable, IteratorAggregate { public function getComments(); }
それは単純ですが、特にあなたがそれを生産環境で使用するのに十分に大胆である場合、それは単純ですが、前の例はいくつかの興味深い概念を簡単に示しています。第一に、仮想エージェントはセットアップと使用が容易であるだけでなく、実行時に異なる実装を混合して、コストのかかるタスクの実行を遅らせるのと比類のないものです(たとえば、ストレージ層の大量のデータの読み込みを遅らせたり、ヘビー級グラフを作成したりします)。第二に、それらは、多くのオブジェクト指向のアプリケーションが苦しむ一般的な剛性と脆弱性の問題を軽減する効果的なワクチンになる方法の典型的な例です。さらに、PHPのオブジェクトモデルはシンプルで閉鎖をサポートするため、これらの機能を巧みに混合し、根底にあるロジックが閉鎖の利点によって駆動されるプロキシを構築することができます。あなたがこの挑戦にあなた自身に対処したいなら、私はあなたが事前に最高のことを願っています。
(imredesiuk / shutterstockの写真)
以上が仮想プロキシのイントロ、パート2の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。