中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP中單例模式有什么用

發布時間:2021-07-27 10:34:42 來源:億速云 閱讀:195 作者:小新 欄目:編程語言

這篇文章主要介紹PHP中單例模式有什么用,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

單例模式絕對是在常用以及面試常問設計模式中排名首位的。一方面它夠簡單,三言兩語就能說明白。另一方面,它又夠復雜,它的實現不僅僅只有一種形式,而且在Java等異步語言中還要考慮多線程加鎖的問題。所以在面試時,千萬不要以為面試官出單例模式的問題就放松了,這個模式真的是可深可淺,也極其能體現一個開發者的水平。因為只要工作過一段時間,不可避免的就會接觸到這個模式。

Gof類圖及解釋

GoF定義:保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。

GoF類圖

PHP中單例模式有什么用

代碼實現

class Singleton
{
    private static $uniqueInstance;
    private $singletonData = '單例類內部數據';

    private function __construct()
    {
        // 構造方法私有化,外部不能直接實例化這個類
    }

    public static function GetInstance()
    {
        if (self::$uniqueInstance == null) {
            self::$uniqueInstance = new Singleton();
        }
        return self::$uniqueInstance;
    }

    public function SingletonOperation(){
        $this->singletonData = '修改單例類內部數據';
    }

    public function GetSigletonData()
    {
        return $this->singletonData;
    }

}

沒錯,核心就是這樣一個單例類,沒別的了。讓靜態變量保存實例化后的自己。當需要這個對象的時候,調用GetInstance()方法獲得全局唯一的一個對象。

$singletonA = Singleton::GetInstance();
echo $singletonA->GetSigletonData(), PHP_EOL;

$singletonB = Singleton::GetInstance();

if ($singletonA === $singletonB) {
    echo '相同的對象', PHP_EOL;
}
$singletonA->SingletonOperation(); // 這里修改的是A
echo $singletonB->GetSigletonData(), PHP_EOL;

客戶端的調用,我們會發現PHP中單例模式有什么用singletonB是完全一樣的對象。

  • 沒錯,從代碼中就可以看出,單例最大的用途就是讓我們的對象全局唯一。

  • 那么全局唯一有什么好處呢?有些類的創建開銷很大,而且并不需要我們每次都使用新的對象,完全可以一個對象進行復用,它們并沒有需要變化的屬性或狀態,只是提供一些公共服務。比如數據庫操作類、網絡請求類、日志操作類、配置管理服務等等

  • 曾經有過面試官問過,單例在PHP中到底是不是唯一的?如果在一個進程下,也就是一個fpm下,當然是唯一的。nginx同步拉起的多個fpm中那肯定就不是唯一的啦。一個進程一個嘛!

  • 單例模式的優點:對唯一實例的受控訪問;縮小命名空間;允許對操作和表示的精化;允許可變數目的實例;比類操作更靈活。

  • Laravel中在IoC容器部分使用了單例模式。關于容器部分的內容我們會在將來的Laravel系列文章中講解。我們可以在Illuminate\Container\Container類中找到singleton方法。它調用了bind方法中的getClosure方法。繼續追蹤會發現他們最終會調用Container的make或build方法來進行實例化類,不管是make還是build方法,他們都會有單例的判斷,也就是判斷類是否被實例化過或者在容器中已存在。build中的if (!$reflector->isInstantiable())。

公司越來越大,但我們的全部公司的花名冊都只有一份(單例類),保存在我們的OA系統中。怕的就是各個部門擁有各自己的花名冊后會產生混亂,比如更新不及時漏掉了其他部門新入職或者離職的員工。其他部門在需要的時候,可以去查看全部的花名冊,也可以在全部花名冊的基礎上建立修改自己部門的部分。但是在OA系統中,其實他們修改的還是那一份總的花名冊中的內容,大家維護的其實都是保存在OA系統服務器中的那唯一一份真實的花名冊

完整代碼:https://github.com/zhangyue0503/designpatterns-php/blob/master/21.singleton/source/singleton.php

實例

既然上面說過數據庫操作類和網絡請求類都很喜歡用單例模式,那么我們就來實現一個Http請求類的單例模式的開發。記得在很早前做Android的時候,還沒有現在這么多的框架,Http請求都是自己封裝的,網上的教程中大部分也都是采取的單例模式。

緩存類圖

PHP中單例模式有什么用

完整源碼:https://github.com/zhangyue0503/designpatterns-php/blob/master/21.singleton/source/singleton-http.php

<?php 

class HttpService{
    private static $instance;

    public function GetInstance(){
        if(self::$instance == NULL){
            self::$instance = new HttpService();
        }
        return self::$instance;
    }

    public function Post(){
        echo '發送Post請求', PHP_EOL;
    }

    public function Get(){
        echo '發送Get請求', PHP_EOL;
    }
}

$httpA = new HttpService();
$httpA->Post();
$httpA->Get();

$httpB = new HttpService();
$httpB->Post();
$httpB->Get();

var_dump($httpA == $httpB);

說明

  • 是不是依然很簡單,這里就不多說這種形式的單例了,我們說說另外幾種形式的單例

  • 在Java等靜態語言中,靜態變量可以直接new對象,在聲明PHP中單例模式有什么用

    instance = new HttpService();。這樣可以省略掉GetInstance()方法,但是這個靜態變量不管用不用都會直接實例化出來占用內存。這種單例就叫做餓漢式單例模式。

  • 我們的代碼和例子很明顯不是餓漢式的,這種形式叫做懶漢式。你要主動的來用GetInstance()獲取,我才會創建對象。

  • 懶漢式在多線程的應用中,如java多線程或者PHP中使用swoole之后,會出現重復創建的問題,而且這多次創建的都不是同一個對象了。這時一般會使用雙重檢測來來確保全局還是只有唯一的一個對象。具體代碼大家可以去自己找一下。餓漢式不會有問題,餓漢式本身就已經給靜態屬性賦值了,不會再改變。

  • 還有一種方式是靜態內部類的創建方式。這種平常就不多見了,它的資源利用率高。將靜態變量放在方法內,使靜態變量成為方法內的變量而不是類中的變量。它可以讓單例對象調用自身的靜態方法和屬性。

以上是“PHP中單例模式有什么用”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

苏尼特右旗| 田阳县| 读书| 进贤县| 安溪县| 梁平县| 盐源县| 吉水县| 马边| 浮梁县| 察雅县| 宜阳县| 万源市| 兴和县| 芦溪县| 涿鹿县| 海城市| 闽清县| 内丘县| 比如县| 屯留县| 水富县| 焦作市| 仙居县| 土默特右旗| 台前县| 松阳县| 阿克苏市| 梁平县| 宜城市| 南召县| 房产| 祁阳县| 安龙县| 东莞市| 隆化县| 梅河口市| 苗栗市| 射洪县| 扎兰屯市| 贡山|