PHP設計模式(一),PHP設計模式(
在碼PHP程式的時候,為了以後更好地維護代碼和理解代碼,用一些合適的設計模式是必不可少的,下面我和大家首先分享下單例模式,有錯誤或者不恰當的地方,還望PHPer們幫我指出。
PHP中的物件存留期間是從該指令碼開始一直到該指令碼結束為止,因此PHP的單例模式只是在一個頁面中(這裡可能包含很多其他頁面,不是狹義的單頁面)多次用到該對象時才會起作用,多次用到時不去重複的new對象(多個人做一個項目時,難免會碰到一次請求中多次執行個體一個對象的情況),將不會耗費不必要的資源(資料控串連操做效果很明顯),還有一點就是可以保證整個指令碼中都是同一個對象,這種模式是怎麼實現的呢,他的實現有幾個要注意的點:
1. 首先就是要將__construct()方法定義為私人方法,這樣就不能通過new來得到一個新的執行個體了,單例模式不能在外部進行執行個體化,這能字自身內部進行執行個體化;
2. 同樣要屏蔽__clone()方法,防止從類外部進行複製
2. 然後就是定義一個用來儲存執行個體的私人變數和擷取私人變數的公有函數getInstance()。
php/** * 設計模式——單例模式 * @author 燕睿濤(luluyrt@163.com) */class Singlemodel{ /** * 儲存Singlemodel執行個體的變數 * @var Singlemodel $_instance */ private static $_instance = null; /** * 屏蔽掉通過new來執行個體化該對象 */ private function __construct(){ //空函數就行 } /**
* 屏蔽掉通過clone來複製該對象
*/
private function __clone(){
//空函數就行
} /** * 通過該方法擷取執行個體,防止多次執行個體化 */ public static function getInstance(){ if(!(self::$_instance instanceof self)){ self::$_instance = new self(); } return self::$_instance; } }
空口無憑,光說這些理論的沒有說服力,下面通過例子來看下具體的效果差異
php/** * 設計模式——單例模式——測試 * @author 燕睿濤(luluyrt@163.com) */class Singlemodel{ /** * 儲存Singlemodel執行個體的變數 * @var Singlemodel $_instance */ private static $_instance = null; private $_link = null; /** * 屏蔽掉通過new來執行個體化該對象(也可以去掉) * 這裡來測試資料庫連接 */ private function __construct(){ $this->_link = mysqli_connect("localhost","root","","mysql"); } /** * 通過該方法擷取執行個體,防止多次執行個體化 */ public static function getInstance(){ if(!(self::$_instance instanceof self)){ self::$_instance = new self(); } return self::$_instance; } /** * 測試1,通過使用單例模式 */ public static function testOne(){ return self::getInstance(); } /** * 測試1,通過使用單例模式 */ public static function testTwo(){ return new self(); } }$obj = array();$begin = microtime(true);for($i=0;$i<100;$i++){ /* * 這裡進行兩次測試,testOne應用了單例模式,testTwo沒有應用單例模式, * 我們分別看看他們佔用的資源和耗費的時間 */ //$obj[$i] = Singlemodel::testOne(); $obj[$i] = Singlemodel::testTwo();}echo "程式運行期間最大記憶體佔用:".memory_get_peak_usage()."bytes\r";echo "程式運行耗時:".floatval(microtime(true) - $begin)."s\r";
先注釋$obj[$i] = Singlemodel::testTwo();這一行,使用單例模式,我們可以得到下面的結果
$obj[$i] = Singlemodel::testOne();,使用非單例模式,我們得到下面結果
可以看到
| 100次測試 |
單例模式 |
普通模式 |
普通/單例(倍) |
| 記憶體(bytes) |
143816 |
847376 |
5.89 |
| 時間(s) |
0.0112519 |
0.2541389 |
22.59 |
| 5次測試 |
|
|
|
| bytes |
140432 |
168984 |
1.20 |
| s |
0.0112612 |
0.0173110 |
1.54 |
可以看到當一次指令碼執行的連結數為100時單例模式的效能比普通模式在記憶體佔用方面好了將近6倍,時間上快了將近23倍,當串連數繼續增加的時候倍數會更大,因為單例模式耗費的記憶體和時間基本沒有變化,非單例模式會不停地增大,這裡要注意一點就是非單例模式情況下連結數增大到一定程度時會報錯"mysqli_connect(): (08004/1040): Trop de connexions in",意思是說並發串連太多了,測試我們可以通過下面的命令查看mysql最大串連數設定,這點需要注意下,免得不知道為什麼報錯。
show variables like 'max_connections';
到這裡,你要是自己測試過就會發現,當連結次數比較少時,差異是比較小的(就像上面的一次請求有5次串連時),其實在一次請求中達到很多次執行個體化也是比較少的,那麼是不是說這個就沒作用了呢,當然不是,你想想看,首先,這樣可以盡量避免多次執行個體化,減小資源消耗;其次,就算是這10ms級的差距,在高並發系統中也是很有用的。我們用它好處多多。
單例模式就這麼多了,下次再講其他設計模式,有什麼不對的地方還望留言或者郵件指出,感激不盡!
send Me~
http://www.bkjia.com/PHPjc/919574.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/919574.htmlTechArticlePHP設計模式(一),PHP設計模式( 在碼PHP程式的時候,為了以後更好地維護代碼和理解代碼,用一些合適的設計模式是必不可少的,下面我...