這篇文章主要介紹了關於php實現代理模式的方法,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下
代理模式(Proxy Pattern) :
給某一個對象提供一個代 理,並由代理對象控制對原對象的引用。代理模式的英 文叫做Proxy或Surrogate,它是一種對象結構型模式
模式動機:
在某些情況下,一個客戶不想或者不能直接引用一個對 象,此時可以通過一個稱之為“代理”的第三者來實現 間接引用。代理對象可以在用戶端和目標對象之間起到 中介的作用,並且可以通過代理對象去掉客戶不能看到 的內容和服務或者添加客戶需要的額外服務。
通過引入一個新的對象(如小圖片和遠程代理對象)來實現對真實對象的操作或者將新的對 象作為真實對象的一個替身,這種實現機制即 為代理模式,通過引入代理對象來間接訪問一 個對象,這就是代理模式的模式動機。
代理模式包含如下角色:
抽象主題角色(Subject):定義了RealSubject和Proxy公用介面,這樣就在任何使用RealSubject的地方都可以使用Proxy。
真正主題角色(RealSubject):定義了Proxy所代表的真實實體。
代理對象(Proxy):儲存一個引用使得代理可以訪問實體,並提供一個與RealSubject介面相同的介面,這樣代理可以用來代替實體(RealSubject)。
UML圖:
代碼實現:
<?phpheader("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、遠程(Remote)代理:為一個位於不同的地址空間的對象提供一個本地 的代理對象,這個不同的地址空間可以是在同一台主機中,也可是在 另一台主機中,遠程代理又叫做大使(Ambassador)。
2、虛擬(Virtual)代理:如果需要建立一個資源消耗較大的對象,先建立一個消耗相對較小的對象來表示,真實對象只在需要時才會被真正建立。
3、Copy-on-Write代理:它是虛擬代理的一種,把複製(複製)操作延遲 到只有在用戶端真正需要時才執行。一般來說,對象的深複製是一個 開銷較大的操作,Copy-on-Write代理可以讓這個操作延遲,只有對象被用到的時候才被複製。
4、保護(Protect or Access)代理:控制對一個對象的訪問,可以給不同的使用者提供不同層級的使用許可權。
5、緩衝(Cache)代理:為某一個目標操作的結果提供臨時的儲存空間,以便多個用戶端可以共用這些結果。
6、防火牆(Firewall)代理:保護目標不讓惡意使用者接近。
7、同步化(Synchronization)代理:使幾個使用者能夠同時使用一個對象而沒有衝突。
8、智能引用(Smart Reference)代理:當一個對象被引用時,提供一些額外的操作,如將此對象被調用的次數記錄下來等。
幾種常用的代理模式:
1、圖片代理:一個很常見的代理模式的應用執行個體就是對大圖瀏覽的控制。
使用者通過瀏覽器訪問網頁時先不載入真實的大圖,而是通過代理對象的方法來進行處理,在代理對象的方法中,先使用一個線程向用戶端瀏覽器載入一個小圖片,然後在後台使用另一個線程來調用大圖片的載入方法將大圖片載入到用戶端。當需要瀏覽大圖片時,再將大圖片在新網頁中顯示。如果使用者在瀏覽大圖時載入工作還沒有完成,可以再啟動一個線程來顯示相應的提示資訊。通過代理技術結合多線程編程將真實圖片的載入放到後台來操作,不影響前台圖片的瀏覽。
2、遠程代理:遠程代理可以將網路的細節隱藏起來,使得用戶端不必考慮網路的存在。客戶完全可以認為被代理的遠程業務對象是局域的而不是遠端,而遠程代理對象承擔了大部分的網路通訊工作。
3、虛擬代理:當一個對象的載入十分耗費資源的時候,虛擬代理的優勢就非常明顯地體現出來了。虛擬代理模式是一種記憶體節省技術,那些佔用大量記憶體或處理複雜的對象將延遲到使用它的時候才建立。
在應用程式啟動的時候,可以用代理對象代替真實對象初始化,節省了記憶體的佔用,並大大加速了系統的啟動時間。
4、動態代理:動態代理是一種較為進階的代理模式,它的典型應用就是Spring AOP。
在傳統的代理模式中,用戶端通過Proxy調用RealSubject類的request()方法,同時還在代理類中封裝了其他方法(如preRequest()和postRequest()),可以處理一些其他問題。
如果按照這種方法使用代理模式,那麼真實主題角色必須是事先已經存在的,並將其作為代理對象的內部成員屬性。如果一個真實主題角色必須對應一個代理主題角色,這將導致系統中的類個數急劇增加,因此需要想辦法減少系統中類的個數,此外,如何在事先不知道真實主題角色的情況下使用代理主題角色,這都是動態代理需要解決的問題。
另一個例子:
設計模式之代理模式(php實現)
github地址:https://github.com/ZQCard/design_pattern
/** * 在代理模式中,我們建立具有現有對象的對象,以便向外界提供功能介面。 * 1、Windows 裡面的捷徑。 * 2、豬八戒去找高翠蘭結果是孫悟空變的,可以這樣理解:把高翠蘭的外貌抽象出來,高翠蘭本人和孫悟空都實現了這個介面, * 豬八戒訪問高翠蘭的時候看不出來這個是孫悟空,所以說孫悟空是高翠蘭代理類。 * 3、買火車票不一定在火車站買,也可以去代售點。 * 4、一張支票或銀行存單是賬戶中資金的代理。支票在市場交易中用來代替現金,並提供對簽發人帳號上資金的控制。 *優點: * 1、職責清晰。 2、高擴充性。 3、智能化。 * 缺點: * 1、由於在用戶端和真實主題之間增加了代理對象,因此有些類型的代理模式可能會造成請求的處理速度變慢。 * 2、實現代理模式需要額外的工作,有些代理模式的實現非常複雜。 * 例子:從伺服器讀取一張圖片的時候,第一次從硬碟讀取,將資來源物件代理,第二次讀取的時候就使用代理對象去讀取。 */
(1)Image.class.php(介面)
<?phpnamespace Proxy;interface Image{ public function display();}
(2)RealImage.class.php
<?phpnamespace 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(代理類)
<?phpnamespace 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
<? ( = ('\\','/', .".class.php" = ProxyImage('a.jpg'->
以上就是本文的全部內容,希望對大家的學習有所協助,更多相關內容請關注topic.alibabacloud.com!