この記事では、主に PHP でプロキシ モードを実装する方法を紹介しますが、これは参考になるものです。今回はそれを共有します。必要な友人は参考にしてください。
プロキシ パターン:
オブジェクトにプロキシを提供し、プロキシ オブジェクトは元のオブジェクトへの参照を制御します。プロキシパターンは、英語ではProxyまたはSurrogateと呼ばれ、オブジェクトの構造パターンです
パターンの動機:
クライアントがオブジェクトを直接参照したくない、または参照できない場合があります。間接参照の実装には「プロキシ」と呼ばれるサードパーティが使用されます。プロキシ オブジェクトは、クライアントとターゲット オブジェクトの間の仲介的な役割を果たすことができ、クライアントが表示できないコンテンツやサービスを削除したり、クライアントが必要とするサービスをプロキシ オブジェクトを通じて追加したりできます。
新しいオブジェクト (小さな画像やリモート プロキシ オブジェクトなど) を導入して実際のオブジェクトを操作する、または新しいオブジェクトを実際のオブジェクトの代わりに使用する、この実装メカニズムがプロキシ モードです。 object オブジェクトに間接的にアクセスするための、これがプロキシ パターンのパターン動機です。
プロキシ モードには次の役割が含まれます。
抽象サブジェクト ロール (Subject): RealSubject と Proxy のパブリック インターフェイスを定義し、RealSubject が使用される場所であればどこでも Proxy を使用できるようにします。
実際のサブジェクトの役割 (RealSubject): プロキシによって表される実際のエンティティを定義します。
プロキシ オブジェクト (Proxy): プロキシがエンティティにアクセスできるように参照を保存し、RealSubject インターフェイスと同じインターフェイスを提供して、プロキシをエンティティ (RealSubject) の代わりに使用できるようにします。
UML 図:
コードの実装:
<?php header("Content-type:text/html;Charset=utf-8");//定义RealSubject和Proxy共同具备的东西 interface Subject{ function say(); function run(); } class RealSubject implements Subject{ private $name; function __construct($name){ $this->name = $name; } function say(){ echo $this->name."在吃饭<br>"; } function run(){ echo $this->name."在跑步<br>"; } } class Proxy implements Subject{ private $realSubject = null; function __construct(RealSubject $realSubject = null){ if(empty($realSubject)){ $this->realSubject = new RealSubject(); }else{ $this->realSubject = $realSubject; } } function say(){ $this->realSubject->say(); } function run(){ $this->realSubject->run(); } }//测试 $subject = new RealSubject("张三"); $proxy = new Proxy($subject);$proxy->say(); $proxy->run(); /*张三在吃饭 张三在跑步*/ ?>
利点:
プロキシモードは呼び出し元と呼び出し先を調整することができ、システムの結合をある程度軽減します。
リモート プロキシを使用すると、クライアントはリモート マシン上のオブジェクトにアクセスできます。リモート マシンのコンピューティング パフォーマンスと処理速度が向上し、クライアントの要求に迅速に応答して処理できます。
小さなオブジェクトを使用して大きなオブジェクトを表すことにより、仮想エージェントはシステム リソースの消費を削減し、システムを最適化し、実行速度を向上させることができます。
保護エージェントは実際のオブジェクトへのアクセスを制御できます。
欠点:
クライアントと実際のトピックの間にプロキシ オブジェクトが追加されるため、一部の種類のプロキシ モードではリクエストの処理速度が遅くなる可能性があります。
プロキシ モードの実装には追加の作業が必要で、一部のプロキシ モードの実装は非常に複雑です。
該当するシナリオ:
プロキシ モードの使用目的に応じて、一般的なプロキシ モードには次のタイプがあります。
1. リモート (リモート) プロキシ: 異なる場所にあるオブジェクトにサービスを提供します。アドレス空間 ローカル プロキシ オブジェクト。この異なるアドレス空間は、同じホストまたは別のホストに存在できます。リモート プロキシはアンバサダーとも呼ばれます。
2. 仮想プロキシ: 大量のリソースを消費するオブジェクトを作成する必要がある場合は、まずそれを表す比較的少量のリソースを消費するオブジェクトを作成します。実際のオブジェクトは必要な場合にのみ作成されます。
3. Copy-on-Write エージェント: クライアントが本当に必要とする場合にのみ実行されるまで、コピー (クローン) 操作を遅らせる仮想エージェントの一種です。一般に、オブジェクトのディープ クローン作成は高コストの操作ですが、コピーオンライト プロキシによってこの操作が遅延する可能性があり、オブジェクトは使用されるときにのみクローン作成されます。
4. 保護 (保護またはアクセス) エージェント: オブジェクトへのアクセスを制御し、さまざまなユーザーにさまざまなレベルの使用許可を提供できます。
5. キャッシュ エージェント: 特定のターゲット操作の結果を一時的に保存するスペースを提供し、複数のクライアントがこれらの結果を共有できるようにします。
6. ファイアウォール エージェント: 悪意のあるユーザーからターゲットを保護します。
7. 同期エージェント: 複数のユーザーが競合することなく同時にオブジェクトを使用できるようにします。
8. スマート参照エージェント: オブジェクトが参照されると、オブジェクトが呼び出された回数を記録するなど、いくつかの追加操作が提供されます。
几种常用的代理模式:
1、图片代理:一个很常见的代理模式的应用实例就是对大图浏览的控制。
用户通过浏览器访问网页时先不加载真实的大图,而是通过代理对象的方法来进行处理,在代理对象的方法中,先使用一个线程向客户端浏览器加载一个小图片,然后在后台使用另一个线程来调用大图片的加载方法将大图片加载到客户端。当需要浏览大图片时,再将大图片在新网页中显示。如果用户在浏览大图时加载工作还没有完成,可以再启动一个线程来显示相应的提示信息。通过代理技术结合多线程编程将真实图片的加载放到后台来操作,不影响前台图片的浏览。
2、远程代理:远程代理可以将网络的细节隐藏起来,使得客户端不必考虑网络的存在。客户完全可以认为被代理的远程业务对象是局域的而不是远程的,而远程代理对象承担了大部分的网络通信工作。
3、虚拟代理:当一个对象的加载十分耗费资源的时候,虚拟代理的优势就非常明显地体现出来了。虚拟代理模式是一种内存节省技术,那些占用大量内存或处理复杂的对象将推迟到使用它的时候才创建。
在应用程序启动的时候,可以用代理对象代替真实对象初始化,节省了内存的占用,并大大加速了系统的启动时间。
4、动态代理:动态代理是一种较为高级的代理模式,它的典型应用就是Spring AOP。
在传统的代理模式中,客户端通过Proxy调用RealSubject类的request()方法,同时还在代理类中封装了其他方法(如preRequest()和postRequest()),可以处理一些其他问题。
如果按照这种方法使用代理模式,那么真实主题角色必须是事先已经存在的,并将其作为代理对象的内部成员属性。如果一个真实主题角色必须对应一个代理主题角色,这将导致系统中的类个数急剧增加,因此需要想办法减少系统中类的个数,此外,如何在事先不知道真实主题角色的情况下使用代理主题角色,这都是动态代理需要解决的问题。
另一个例子:
github地址:https://github.com/ZQCard/design_pattern
/** * 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。 * 1、Windows 里面的快捷方式。 * 2、猪八戒去找高翠兰结果是孙悟空变的,可以这样理解:把高翠兰的外貌抽象出来,高翠兰本人和孙悟空都实现了这个接口, * 猪八戒访问高翠兰的时候看不出来这个是孙悟空,所以说孙悟空是高翠兰代理类。 * 3、买火车票不一定在火车站买,也可以去代售点。 * 4、一张支票或银行存单是账户中资金的代理。支票在市场交易中用来代替现金,并提供对签发人账号上资金的控制。 *优点: * 1、职责清晰。 2、高扩展性。 3、智能化。 * 缺点: * 1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 * 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。 * 例子:从服务器读取一张图片的时候,第一次从硬盘读取,将资源对象代理,第二次读取的时候就使用代理对象去读取。 */
(1)Image.class.php(接口)
<?php namespace Proxy;interface Image { public function display(); }
(2)RealImage.class.php
<?php namespace Proxy;class RealImage implements Image { private $fileName; public function __construct($fileName) { $this->fileName = $fileName; $this->loadFromDisk($fileName); } public function display() { print_r("Displaying ". $this->fileName); echo '<pre/>'; } private function loadFromDisk($fileName) { print_r("Loading ". $fileName); echo '<pre/>'; } }
(3)ProxyImage.class.php(代理类)
<?php namespace Proxy;class ProxyImage implements Image { private $realImage; private $fileName; public function __construct($fileName) { $this->fileName = $fileName; } public function display() { if ($this->realImage == null){ $this->realImage = new RealImage($this->fileName); } return $this->realImage->display(); } }
(4)proxy.php
3b7462c1ecb9e636460d764deddddf92
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
以上がPHPでプロキシモードを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。