自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

PHP設(shè)計(jì)模式漫談之代理模式

原創(chuàng)
開(kāi)發(fā) 后端 前端
PHP也有設(shè)計(jì)模式?是的,我們經(jīng)常看到關(guān)于Java和.NET平臺(tái)上設(shè)計(jì)模式的論述和講解,其實(shí),在PHP 5對(duì)面向?qū)ο蟮闹С指油晟浦螅O(shè)計(jì)模式的應(yīng)用也可引入到PHP中并發(fā)揮重要作用。

【51CTO獨(dú)家特稿】設(shè)計(jì)模式( Design Pattern)是從建筑設(shè)計(jì)領(lǐng)域引入到計(jì)算機(jī)科學(xué)的。設(shè)計(jì)模式是對(duì)軟件設(shè)計(jì)中普遍存在(且反復(fù)出現(xiàn))的各種問(wèn)題,所提出的解決方案。設(shè)計(jì)模式并不直接用來(lái)完成程序碼的編寫,而是描述在各種不同情況下,要怎么解決問(wèn)題的一種方案。

更多關(guān)于PHP設(shè)計(jì)模式方面的入門與應(yīng)用可以參考51CTO之前的報(bào)道《使用設(shè)計(jì)模式改善程序結(jié)構(gòu)》以及《架構(gòu)、框架、設(shè)計(jì)模式之間的關(guān)系簡(jiǎn)述》。

我們經(jīng)??吹疥P(guān)于Java和.NET平臺(tái)上設(shè)計(jì)模式的論述和講解,其實(shí),在PHP 5對(duì)面向?qū)ο蟮闹С指油晟浦?,設(shè)計(jì)模式的應(yīng)用也可引入到PHP中并發(fā)揮重要作用。51CTO.com將從本周起以每周一期的形式連載《PHP設(shè)計(jì)模式漫談》的系列文章,以理論與代碼實(shí)例相結(jié)合的方式講解PHP中的設(shè)計(jì)模式。希望對(duì)從事PHP研發(fā)的讀者有所幫助。

今天我們要談的是PHP設(shè)計(jì)模式中的代理模式(Proxy),它是對(duì)簡(jiǎn)單處理程序(或指針)的增強(qiáng),用于引用一個(gè)對(duì)象:這個(gè)指針被代理(Proxy)對(duì)象取代,代理對(duì)象位于客戶端(Client)和真實(shí)執(zhí)行程序之間,指針有一個(gè)可被多個(gè)目標(biāo)利用的鉤子。

從技術(shù)上講,這種模式在客戶端和真實(shí)主體(RealSubject)之間插入一個(gè)代理對(duì)象,維護(hù)subject接口和用不同的方式委派它的方法。代理可以透明地做任何事情:懶散創(chuàng)建RealSubject或載入數(shù)據(jù),與其它機(jī)器交換消息,寫時(shí)復(fù)制策略等。這與HTTP代理有點(diǎn)類似,其客戶端(如瀏覽器)和應(yīng)用程序依賴于與HTTP服務(wù)器的聯(lián)系,代理在管理連接時(shí)可以完成其它任務(wù),如訪問(wèn)控制和緩存大型下載文件。

PHP設(shè)計(jì)模式中的代理模式
PHP設(shè)計(jì)模式中的代理模式示例

代理模式的對(duì)象圖與裝飾模式對(duì)象圖在結(jié)構(gòu)上類似,但表達(dá)的目的各有不同,裝飾者給對(duì)象動(dòng)態(tài)增加行為,而代理則控制來(lái)自客戶端的訪問(wèn)。此外,代理只在需要時(shí)才創(chuàng)建RealSubject。 

參與者

客戶端(Client):取決于主體(Subject)實(shí)現(xiàn);

主體(Subject):RealSubject的抽象;

真實(shí)主體(RealSubject):完成代價(jià)高昂的工作或包含大量的數(shù)據(jù);

代理(Proxy):為Client提供一個(gè)與Subject一致的引用,僅在需要時(shí)才創(chuàng)建RealSubject實(shí)例或與RealSubject實(shí)例通信。

下面是兩個(gè)被廣泛使用的代理模式例子:

1、對(duì)象-關(guān)系映射(Orms)在運(yùn)行中創(chuàng)建代理作為實(shí)體類的子類,以實(shí)現(xiàn)懶散加載(虛擬代理),這個(gè)代理會(huì)覆蓋所有實(shí)體方法,在前面追加一個(gè)載入程序,在方法被真正調(diào)用前不會(huì)包含任何數(shù)據(jù),Orms代理支持對(duì)象間的雙向關(guān)系,不用加載整個(gè)數(shù)據(jù)庫(kù),因?yàn)樗鼈儽恢糜诋?dāng)前加載對(duì)象圖的邊界。

2、Java RMI使用遠(yuǎn)程代理對(duì)象(遠(yuǎn)程代理),當(dāng)它們的方法被調(diào)用時(shí),代理序列化參數(shù),執(zhí)行網(wǎng)絡(luò)上的請(qǐng)求,委托調(diào)用另一個(gè)節(jié)點(diǎn)上的真實(shí)對(duì)象,這種技術(shù)允許透明地調(diào)用遠(yuǎn)程對(duì)象,不用擔(dān)心它們是否在同一臺(tái)機(jī)器上,但這種透明度很容易會(huì)使執(zhí)行速度變慢。

下面的代碼示例實(shí)現(xiàn)了一個(gè)ImageProxy,推遲了圖像數(shù)據(jù)的加載。

  1. /**  
  2.  * Subject interface.  
  3.  * Client depends only on this abstraction.  
  4.  */ 
  5. interface Image  
  6. {  
  7.     public function getWidth();  
  8.  
  9.     public function getHeight();  
  10.  
  11.     public function getPath();  
  12.  
  13.     /**  
  14.      * @return string   the image's byte stream  
  15.      */ 
  16.     public function dump();  
  17. }  
  18.  
  19. /**  
  20.  * Abstract class to avoid repetition of boilerplate code in the Proxy  
  21.  * and in the Subject. Only the methods which can be provided without  
  22.  * instancing the RealSubject are present here.  
  23.  */ 
  24. abstract class AbstractImage implements Image  
  25. {  
  26.     protected $_width;  
  27.     protected $_height;  
  28.     protected $_path;  
  29.     protected $_data;  
  30.  
  31.     public function getWidth()  
  32.     {  
  33.         return $this->_width;  
  34.     }  
  35.  
  36.     public function getHeight()  
  37.     {  
  38.         return $this->_height;  
  39.     }  
  40.  
  41.     public function getPath()  
  42.     {  
  43.         return $this->_path;  
  44.     }  
  45. }  
  46.  
  47. /**  
  48.  * The RealSubject. Always loads the image, even if no dump of the data  
  49.  * is required.  
  50.  */ 
  51. class RawImage extends AbstractImage  
  52. {  
  53.     public function __construct($path)  
  54.     {  
  55.         $this->_path = $path;  
  56.         list ($this->_width, $this->_height) = getimagesize($path);  
  57.         $this->_data = file_get_contents($path);  
  58.     }  
  59.  
  60.     public function dump()  
  61.     {  
  62.         return $this->_data;  
  63.     }  
  64. }  
  65.  
  66. /**  
  67.  * Proxy. Defers loading the image data until it becomes really mandatory.  
  68.  * This class does its best to postpone the very expensive operations  
  69.  * such as the actual loading of the BLOB.  
  70.  */ 
  71. class ImageProxy extends AbstractImage  
  72. {  
  73.     public function __construct($path)  
  74.     {  
  75.         $this->_path = $path;  
  76.         list ($this->_width, $this->_height) = getimagesize($path);  
  77.     }  
  78.  
  79.     /**  
  80.      * Creates a RawImage and exploits its functionalities.  
  81.      */ 
  82.     protected function _lazyLoad()  
  83.     {  
  84.         if ($this->_realImage === null) {  
  85.             $this->_realImage = new RawImage($this->_path);  
  86.         }  
  87.     }  
  88.  
  89.     public function dump()  
  90.     {  
  91.         $this->_lazyLoad();  
  92.         return $this->_realImage->dump();  
  93.     }  
  94. }  
  95.  
  96. /**  
  97.  * Client class that does not use the data dump of the image.  
  98.  * Passing blindly a Proxy to this class and to other Clients makes sense  
  99.  * as the data would be loaded anyway when Image::dump() is called.  
  100.  */ 
  101. class Client  
  102. {  
  103.     public function tag(Image $img)  
  104.     {  
  105.         return '$img->getPath() . '" alt="" width="' 
  106.              . $img->getWidth() . '" height="'   
  107.              . $img->getHeight() . '" />';  
  108.     }  
  109. }  
  110.  
  111. $path = '/home/giorgio/shared/Immagini/kiki.png';  
  112. $client = new Client();  
  113.  
  114. $image = new RawImage($path); // loading of the BLOB takes place  
  115. echo $client->tag($image), "\n";  
  116.  
  117. $proxy = new ImageProxy($path);  
  118. echo $client->tag($proxy), "\n"// loading does not take place even here 

以上代碼實(shí)現(xiàn)了PHP的代理模式。簡(jiǎn)單來(lái)講,代理模式就是為其他對(duì)象提供一個(gè)代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。

關(guān)于設(shè)計(jì)模式的其他方面

我們知道了什么是設(shè)計(jì)模式以及PHP設(shè)計(jì)模式中的代理模式。這里還有一些關(guān)于設(shè)計(jì)模式的基本概念應(yīng)該被熟知。

◆算法不能算是一種設(shè)計(jì)模式,因?yàn)樗惴ㄖ饕怯脕?lái)解決計(jì)算上的問(wèn)題,而非設(shè)計(jì)上的問(wèn)題。

◆面向?qū)ο笤O(shè)計(jì)模式通常以類別或物件來(lái)描述其中的關(guān)系和相互作用,但不涉及用來(lái)完成應(yīng)用程序的特定類別或物件。

◆設(shè)計(jì)模式主要是使不穩(wěn)定的依賴于相對(duì)穩(wěn)定、具體依賴于相對(duì)抽象,避免會(huì)引起麻煩的緊耦合,以增強(qiáng)軟件設(shè)計(jì)面對(duì)并適應(yīng)變化的能力。

◆并非所有的軟件模式都是設(shè)計(jì)模式,設(shè)計(jì)模式特指軟件設(shè)計(jì)層次上的問(wèn)題。還有其它非設(shè)計(jì)模式的模式,如架構(gòu)模式。 

我們會(huì)在下周繼續(xù)為您連載《PHP設(shè)計(jì)模式漫談》,敬請(qǐng)期待。

【編輯推薦】

  1. 鐘勝輝談PHP發(fā)展的現(xiàn)狀和前景
  2. Java設(shè)計(jì)模式與應(yīng)用淺談
  3. 架構(gòu)、框架、設(shè)計(jì)模式之間的關(guān)系簡(jiǎn)述
  4. 專題:PHP開(kāi)發(fā)基礎(chǔ)入門

 原文:Practical Php Patterns: Proxy

鏈接:http://giorgiosironi.blogspot.com/2010/02/practical-php-patterns-proxy.html

 

 

責(zé)任編輯:佚名 來(lái)源: 51CTO.com
相關(guān)推薦

2010-04-19 09:30:00

工廠模式PHP設(shè)計(jì)模式

2010-04-13 08:54:28

PHP設(shè)計(jì)模式命令模式

2010-04-08 09:27:04

PHP設(shè)計(jì)模式結(jié)構(gòu)模式

2010-04-21 08:38:18

解釋器模式PHP設(shè)計(jì)模式

2010-04-01 09:10:03

PHP設(shè)計(jì)模式責(zé)任鏈模式

2010-04-29 08:53:11

PHP迭代器模式

2010-05-06 08:44:37

調(diào)解者模式

2012-02-29 09:41:14

JavaScript

2012-01-13 15:59:07

2021-06-29 08:54:23

設(shè)計(jì)模式代理模式遠(yuǎn)程代理

2022-09-07 08:25:08

代理模式設(shè)計(jì)模式代碼

2011-04-21 09:46:41

設(shè)計(jì)模式

2011-04-06 11:41:25

Java動(dòng)態(tài)代理

2024-04-16 00:07:36

設(shè)計(jì)模式代理模式替身

2020-08-21 07:23:50

工廠模式設(shè)計(jì)

2024-02-26 11:52:38

代理模式設(shè)計(jì)

2022-11-30 17:05:33

代碼程序場(chǎng)景

2021-06-09 08:53:34

設(shè)計(jì)模式策略模式工廠模式

2015-09-08 13:39:10

JavaScript設(shè)計(jì)模式

2021-12-24 07:50:45

責(zé)任鏈模式設(shè)計(jì)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)