PHP設計模式-單例模式

單例模式(Singleton Pattern 單件模式或單元素模式)

單例模式確保某個類只有一個實例,而且自行實例化并向整個系統(tǒng)提供這個實例。

單例模式是一種常見的設計模式,在計算機系統(tǒng)中,線程池、緩存、日志對象、對話框、打印機、數據庫操作、顯卡的驅動程序常被設計成單例。

單例模式分3種:懶漢式單例、餓漢式單例、登記式單例。

單例模式有以下3個特點:

1.只能有一個實例。

2.必須自行創(chuàng)建這個實例。

3.必須給其他對象提供這一實例。

那么為什么要使用PHP單例模式?

PHP一個主要應用場合就是應用程序與數據庫打交道的場景,在一個應用中會存在大量的數據庫操作,針對數據庫句柄連接數據庫的行為,使用單例模式可以避免大量的new操作。因為每一次new操作都會消耗系統(tǒng)和內存的資源。

在以往的項目開發(fā)中,沒使用單例模式前的情況如下:

//初始化一個數據庫句柄$db = new DB(...);

//比如有個應用場景是添加一條用戶信息$db->addUserInfo();

......

//然而我們要在另一地方使用這個用戶信息,這時要用到數據庫句柄資源,可能會這么做

......

function test() {

$db = new DB(...);

$db->getUserInfo();

......

有些朋友也許會說,可以直接使用global關鍵字!

global $db;

......

的確global可以解決問題,也起到單例模式的作用,但在OOP中,我們拒絕這種編碼。因為global存在安全隱患(全局變量不受保護的本質)。

全局變量是面向對象程序員遇到的引發(fā)BUG的主要原因之一。這是因為全局變量將類捆綁于特定的環(huán)境,破壞了封裝。如果新的應用程序無法保證一開始就定義了相同的全局變量,那么一個依賴于全局變量的類就無法從一個應用程序中提取出來并應用到新應用程序中。

確切的講,單例模式恰恰是對全局變量的一種改進,避免那些存儲唯一實例的全局變量污染命名空間。你無法用錯誤類型的數據覆寫一個單例。這種保護在不支持命名空間的PHP版本里尤其重要。因為在PHP中命名沖突會在編譯時被捕獲,并使腳本停止運行。

PHP單例模式實例:

先看圖:

image.png

上面的對象圖中,有一個“單例對象”,而“客戶甲”、“客戶乙”和“客戶丙”是單例對象的三個客戶對象??梢钥吹剑械目蛻魧ο蠊蚕硪粋€單例對象。而且從單例對象到自身的連接線可以看出,單例對象持有對自己的引用。

<?php

class User {

//靜態(tài)變量保存全局實例

private static $_instance = null;

//私有構造函數,防止外界實例化對象

private function __construct() {

}

//私有克隆函數,防止外辦克隆對象

private function __clone() {

}

//靜態(tài)方法,單例統(tǒng)一訪問入口

static public function getInstance() {

    if (is_null ( self::$_instance ) || isset ( self::$_instance )) {

        self::$_instance = new self ();

    }

    return self::$_instance;

}

public function getName() {

    echo 'hello world!';

}

}

?>

單例模式的優(yōu)缺點:

優(yōu)點:

1. 改進系統(tǒng)的設計

2. 是對全局變量的一種改進

缺點:

1. 難于調試

2. 隱藏的依賴關系

3. 無法用錯誤類型的數據覆寫一個單例

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容