代理模式 以及 php對象實例化的應用場景

0 代理模式

代理模式,即通過 代理對象 訪問 目標對象,可以在目標對象實現的基礎上,增加額外的功能性操作

  • 靜態代理

    即在代理類中重寫需要調用的方法,實現思路直接,但需要維護很多代理類

  • 動態代理

    相關內容作爲參數傳入,如java的 newProxyInstance

1 php適合代理模式的__call()方法

  • 當對象調用不存在 或者 受權限限制的方法時,__call()會被自動調用
  • php重載(overload):作爲一種弱類型語言,本身不能像java, c++一樣直接實現重載;但可通過特殊方法實現,如 __call
class Magic {
  function __call($name,$arguments) {
    if($name=='foo') {
        if(is_int($arguments[0])) $this->foo_for_int($arguments[0]);
        if(is_string($arguments[0])) $this->foo_for_string($arguments[0]);
    }
  } 
  private function foo_for_int($x) {
        print("oh an int!");
  }  
  private function foo_for_string($x) {
        print("oh a string!");
  }
} 
$x = new Magic();
$x->foo(3);
$x->foo("3");

2 對象實例化的兩種方式

在使用該對象時直接new

  • 程序運行時,內存大致分爲:棧空間段、堆空間段、代碼段、初始化靜態段。每次實例化一次類,都會創建一個對象,會在 【棧空間段】開闢一個新的空間來保存該對象。
  • 因此在不需要保持某一對象多個實例時,這種方式很不可取
class Test {
  	function a () {
      $person1 = new Person();
      $person1->getAge();
    }
  
    function b () {
      $person2 = new Person();
      $person1->getSex();
    }
}

__construct構造方法

  • 具有構造函數的類會在每次創建新對象時先調用此方法
  • 避免了對 對象創建多個實例的問題
class Test {
  	private $person;
 
 		function __construct() {
       $this->person = new Person();
    }
  
    function a () {
      $person->getAge();
    }
  
    function b () {
      $person->getSex();
    }
}

3 爲什麼需要代理模式

構建一個完整的項目時,考慮到 【埋點 / 性能監控 / 緩存等】等操作,比如這樣一個簡單的記錄

function a() {
	echo microtime(true);
  $person->getAge();
  echo microtime(true);
} 

類似操作變多時,會帶來兩個問題:1. 需要在各個調用處單獨處理,代碼冗餘; 2. 修改時(如監控變動)需多處修改。因此考慮代理模式設計,思路如下:
代理模式設計思路

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章