在之前的文章《深入淺析PHP中的模板方法模式》中我們介紹了PHP中的模板方法模式,下面本篇文章帶大家了解一下PHP設計模式中的單例模式。
單例模式絕對是在常用以及面試常問設計模式中排名首位的。一方面它夠簡單,三言兩語就能說明白。另一方面,它又夠複雜,它的實作不只一種形式,在Java等非同步語言中還要考慮多執行緒加鎖的問題。所以在面試時,千萬不要以為面試官出單例模式的問題就放鬆了,這個模式真的是可深可淺,也極其能體現一個開發者的水平。因為只要工作過一段時間,不可避免的就會接觸到這個模式。
GoF定義:保證一個類別只有一個實例,並提供一個存取它的全域存取點。
GoF類別圖
#程式碼實作
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;
客戶端的調用,我們會發現singletonB是完全一樣的物件。
公司越來越大,但我們的整個公司的花名冊都只有一份(單例類),保存在我們的OA系統中。怕的就是各部門擁有各自己的花名冊後會產生混亂,例如更新不及時漏掉了其他部門新入職或離職的員工。其他部門在需要的時候,可以去查看全部的花名冊,也可以在全部花名冊的基礎上建立修改自己部門的部分。但在OA系統中,其實他們修改的還是那一份總的花名冊中的內容,大家維護的其實都是保存在OA系統伺服器中的那唯一一份真實的花名冊
#完整程式碼:https://github.com/zhangyue0503/designpatterns-php/blob/master/21.singleton/source/singleton.php
既然上面說過資料庫操作類別和網路請求類別都很喜歡用單例模式,那麼我們就來實作一個Http請求類別的單例模式的開發。記得在很早前做Android的時候,還沒有現在這麼多的框架,Http請求都是自己封裝的,網路上的教學大部分也都是採取的單例模式。
快取類別圖
#完整原始碼: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對象,在宣告
instance = new HttpService();。這樣可以省略掉GetInstance()方法,但是這個靜態變數不管用不用都會直接實例化出來佔用記憶體。這種單例就叫做餓漢式單例模式。
原文網址:https://juejin.cn/post/6844903990585458702
作者:硬核心專案經理
推薦學習: 《PHP影片教學》
以上是一起聊聊PHP中的單例模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!