<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                **代理(Proxy)模式:** 為某對象提供一種代理以控制對該對象的訪問。即客戶端通過代理**間接地訪問**該對象,從而限制、增強或修改該對象的一些特性。 常見的代理模式:遠程代理、虛擬代理、保護代理、智能引用代理 **代理模式的主要優點有:** * 代理模式在客戶端與目標對象之間起到一個中介作用和保護目標對象的作用; * 代理對象可以擴展目標對象的功能; * 代理模式能將客戶端與目標對象分離,在一定程度上降低了系統的耦合度; **其主要缺點是:** * 在客戶端和目標對象之間增加一個代理對象,會造成請求處理速度變慢; * 增加了系統的復雜度; ## **代理模式的應用場景** 前面分析了代理模式的結構與特點,現在來分析以下的應用場景。 * **遠程代理**,這種方式通常是為了隱藏目標對象存在于不同地址空間的事實,方便客戶端訪問。例如,用戶申請某些網盤空間時,會在用戶的文件系統中建立一個虛擬的硬盤,用戶訪問虛擬硬盤時實際訪問的是網盤空間。 * **虛擬代理**,這種方式通常用于要創建的目標對象開銷很大時。例如,下載一幅很大的圖像需要很長時間,因某種計算比較復雜而短時間無法完成,這時可以先用小比例的虛擬代理替換真實的對象,消除用戶對服務器慢的感覺。 * **安全代理**,這種方式通常用于控制不同種類客戶對真實對象的訪問權限。 * **智能指引**,主要用于調用目標對象時,代理附加一些額外的處理功能。例如,增加計算真實對象的引用次數的功能,這樣當該對象沒有被引用時,就可以自動釋放它。 * **延遲加載**,指為了提高系統的性能,延遲對目標的加載。例如,[Hibernate](http://c.biancheng.net/hibernate/)中就存在屬性的延遲加載和關聯表的延時加載。 #### **模式的結構** 1. 抽象主題(Subject)類:通過接口或抽象類聲明真實主題和代理對象實現的業務方法。 2. 真實主題(Real Subject)類:實現了抽象主題中的具體業務,是代理對象所代表的真實對象,是最終要引用的對象。 3. 代理(Proxy)類:提供了與真實主題相同的接口,其內部含有對真實主題的引用,它可以訪問、控制或擴展真實主題的功能。 ![](https://img.kancloud.cn/20/98/2098786632a6bf2aa00b80d1da3570cd_672x355.png) ``` <?php class ProxyTest { public static function main() { $proxy=new Proxy(); $proxy->Request(); } } //抽象主題 interface Subject { public function Request(); } //真實主題 class RealSubject implements Subject { public function Request() { echo "訪問真實主題方法..."; } } //代理 class Proxy implements Subject { private $realSubject=null; public function Request() { if ($this->realSubject==null) { $this->realSubject=new RealSubject(); } $this->preRequest(); $this->realSubject->Request(); $this->postRequest(); } public function preRequest() { echo "訪問真實主題之前的預處理。"; } public function postRequest() { echo "訪問真實主題之后的后續處理。"; } } ProxyTest::main(); ``` ``` //公司內部類 class User { public function getName() { return '張三'; } public function getType() { return '付費用戶'; } } //代理接口定義,例如開放平臺 interface UserInterface { function getName(); } //代理對象 class UserProxy implements UserInterface { protected $_user; function __construct() { $this->_user = new User(); } public function getName() { return $this->_user->getName(); } } //公司內部調用 $user = new User(); printf("user name:%sn", $user->getName()); printf("user type:%sn", $user->getType()); //公司外部調用(開放給用戶的) $user = new UserProxy(); printf("user name:%sn", $user->getName()); printf("user type:%sn", $user->getType()); //不能訪問,及時知道內部對象有這個方法 ``` ## 代理模式的擴展 在前面介紹的代理模式中,代理類中包含了對真實主題的引用,這種方式存在兩個缺點。 1. 真實主題與代理主題一一對應,增加真實主題也要增加代理。 2. 設計代理以前真實主題必須事先存在,不太靈活。采用動態代理模式可以解決以上問題,如[Spring](http://c.biancheng.net/spring/)AOP,其結構圖如圖 4 所示。 ![](https://img.kancloud.cn/6e/60/6e60cbe965d2d44df823d6d37176962b_698x628.png) 變相的動態代理 ``` //調用B的show方法時候去調用A的show方法 class A{ function show($param=20){ echo "classA的show方法,參數值為{$param}"; } } class B{ private $obj; function __construct(){ $this->obj = new A(); } function __call($name, $arguments) { $ref = new ReflectionClass($this->obj); //檢查方法是否已定義 if ($ref->hasMethod($name)){ //獲取一個類方法的 ReflectionMethod對象。相當于new ReflectionMethod('class', 'myMethod') $method = $ref->getMethod($name); if ($method->isPublic()&&!$method->isAbstract()&&count($arguments)<1){ if ($method->isStatic()){ //如果是靜態方法,不需要傳入調用的對象 $method->invoke(null); }else{ $method->invoke($this->obj); } }else{ if ($method->isStatic()){ //如果是靜態方法,不需要傳入調用的對象 $method->invokeArgs(null,$arguments); }else{ $method->invokeArgs($this->obj,$arguments); } } } } } $b=new B(); $b->show();//classA的show方法,參數值為20 $b->show(21);//classA的show方法,參數值為21 ``` **動態代理:** ``` //真實角色接口類 AbstractSubject interface IGamePlayer { // 登錄游戲 public function login(String $user, String $password); // 殺怪 public function killBoss(); // 升級 public function upgrade(); } //真實角色類:RealSubject class GamePlayer implements IGamePlayer { private $name = ""; // 我的代理 IGamePlayer類型 private $proxy = null; public function __construct(String $_name) { $this->name = $_name; } /** * @Override */ public function login(String $user, String $password) { print_r("登錄名為【" . $user . "】的用戶【" . $this->name . "】登錄成功!<br>"); } /** * @Override */ public function killBoss() { print_r($this->name . "在打怪!<br>"); } /** * @Override */ public function upgrade() { print_r($this->name . " 已升了一級!<br>"); } } //動態代理接口 Invocationhandler interface InvocationHandler{ public function invoke($proxy, $function_name, $param); } //動態代理類:DynamicProxy class GamePlayIH implements InvocationHandler { // 被代理實例Object private $obj = null; // 我要代理誰 public function __construct($_obj) { $this->obj = $_obj; } /** * @Override */ public function invoke($proxy, $function_name,$param){ //檢查方法是否已定義 if ($proxy->hasMethod($function_name)){ //獲取一個類方法的 ReflectionMethod對象。相當于new ReflectionMethod('class', 'myMethod') $method = $proxy->getMethod($function_name); if ($method->isPublic()&&!$method->isAbstract()&&count($param)<1){ if ($method->isStatic()){ //如果是靜態方法,不需要傳入調用的對象 $method->invoke(null); }else{ $method->invoke($this->obj); } }else{ if ($method->isStatic()){ //如果是靜態方法,不需要傳入調用的對象 $method->invokeArgs(null,$param); }else{ $method->invokeArgs($this->obj,$param); } } } } public function __call($function_name,$param){ $ref = new ReflectionClass($this->obj); $this->invoke($ref,$function_name,$param); } } class Client { public static function main() { // 定義一個癡迷的玩家 IGamePlayer $player = new GamePlayer("猿哥"); //InvocationHandler $proxy = new GamePlayIH($player); // 登錄 $proxy->login("oneape15", "pwd123"); //開始殺怪 $proxy->killBoss(); // 升級 $proxy->upgrade(); } } Client::main(); 結果: 登錄名為【oneape15】的用戶【猿哥】登錄成功! 猿哥在打怪! 猿哥 已升了一級! ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看