摘要:實現(xiàn)我們在這里引入了一個私有的構(gòu)造函數(shù),這樣,外部就無法實例化這個對象了。對于這個類,我們無法生成第二個對象,因為它的構(gòu)造函數(shù)是私有的,并且方法是私有的,而且,在判斷已經(jīng)有了一個實例的情況下默認(rèn)返回該實例。這就是單例模式。
問題 惱人的全局變量
在 PHP 中,甚至不只 PHP 中,我們都會用到全局變量,以保存全局狀態(tài)??墒牵肿兞渴侨止蚕淼?,任何地方任何代碼都有可能將其覆蓋。例如,我們定義一個全局變量叫做 PHONE。我們在某一行代碼中,將其定義成了 iPhone,但是我們不小心在另一行代碼中將其覆寫成了 Nokia。這就非常的尷尬了,因為本來我們并不想它被覆寫。
繁瑣的參數(shù)傳遞在一個系統(tǒng)中,我們會定義許多的方法,生成很多的對象。有時候,我們會使用很多的方法,對同一個對象做操作。在不使用全局變量的情況下,我們需要將對象作為參數(shù)傳入方法中。但是這樣傳遞同一個對象,可能會造成混亂,還可能造成不必要的依賴。
其實我們只需要一個全局可訪問的對象就可以解決這個,但是全局變量又會出現(xiàn)我們上面的說的問題。
解決 目標(biāo)我們要解決這些問題,我們對這樣的對象有下面的幾個目標(biāo)。
這個對象,無論在哪里都能訪問,就想全局變量一樣。
這個對象,和全局變量不同,不能被覆寫。
這個對象,整個系統(tǒng)中只存在一個,對它的修改在整個系統(tǒng)中都能被感知到。
以上的幾個目標(biāo),就是我們所需要的,也就是單例模式的特征。
UML 實現(xiàn)class Preference { private static $instance; private $props = []; private __construct() {} public static function getInstance() { if (empty(self::$instance)) { self::$instance = new Preference(); } return self::$instance; } public function setProperty($key, $value) { $this->props[$key] = $value; } public function getProperty($key) { return $this->props[$key]; } private function __clone() {} private function __sleep() {} private function __wakeup() {} }
我們在這里引入了一個私有的構(gòu)造函數(shù),這樣,外部就無法實例化這個對象了。同時,我們使用 getInstance 方法來獲取具體的實例,而無法去覆寫它,這就達(dá)成了第二個目標(biāo)。
由于 $instance 和 getInstance 都是靜態(tài)的,所以我們可以通過 Preference::getInstance() 訪問,具體的實例。這樣就使得全局都可以訪問到它了,它就像全局變量一樣了,這就達(dá)成了第一個目標(biāo)了。
對于這個類,我們無法生成第二個對象,因為它的構(gòu)造函數(shù)是私有的,并且 __clone 方法是私有的,而且,getInstance 在判斷已經(jīng)有了一個實例的情況下默認(rèn)返回該實例。這就達(dá)成了第三個目標(biāo)了。
同時,我們也盡量避免序列化這個實例,所以我們給 __wakeup 和 __sleep 這兩個魔術(shù)方法私有。
這就是單例模式。
后記對于單例模式,其實沒有那么高大上。只不過是更改的對象的訪問范圍,以及對象始終存在,僅此而已。
最后,本文章是作者在學(xué)習(xí)設(shè)計模式時的感想。部分參考自《深入 PHP 面向?qū)ο蟆⒛J脚c實踐(第 3 版)》。如有錯誤,感謝大神不吝賜教。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/30679.html
摘要:模塊化是隨著前端技術(shù)的發(fā)展,前端代碼爆炸式增長后,工程化所采取的必然措施。目前模塊化的思想分為和。特別指出,事件不等同于異步,回調(diào)也不等同于異步。將會討論安全的類型檢測惰性載入函數(shù)凍結(jié)對象定時器等話題。 Vue.js 前后端同構(gòu)方案之準(zhǔn)備篇——代碼優(yōu)化 目前 Vue.js 的火爆不亞于當(dāng)初的 React,本人對寫代碼有潔癖,代碼也是藝術(shù)。此篇是準(zhǔn)備篇,工欲善其事,必先利其器。我們先在代...
摘要:來自不同視圖的行為需要變更同一狀態(tài)。圖解后端的行為,響應(yīng)在上的用戶輸入導(dǎo)致的狀態(tài)變化。中的非常類似于事件每個都有一個字符串的事件類型和一個回調(diào)函數(shù)。 什么是Vuex? Vuex 是一個專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化。 Vuex采用和Redux類似的單向數(shù)據(jù)流的方式來管理數(shù)據(jù)。用戶...
摘要:中的詳解必修個多線程問題總結(jié)個多線程問題總結(jié)有哪些源代碼看了后讓你收獲很多,代碼思維和能力有較大的提升有哪些源代碼看了后讓你收獲很多,代碼思維和能力有較大的提升開源的運行原理從虛擬機工作流程看運行原理。 自己實現(xiàn)集合框架 (三): 單鏈表的實現(xiàn) 自己實現(xiàn)集合框架 (三): 單鏈表的實現(xiàn) 基于 POI 封裝 ExcelUtil 精簡的 Excel 導(dǎo)入導(dǎo)出 由于 poi 本身只是針對于 ...
摘要:基礎(chǔ)知識復(fù)習(xí)后端掘金的作用表示靜態(tài)修飾符,使用修飾的變量,在中分配內(nèi)存后一直存在,直到程序退出才釋放空間。將對象編碼為字節(jié)流稱之為序列化,反之將字節(jié)流重建成對象稱之為反序列化。 Java 學(xué)習(xí)過程|完整思維導(dǎo)圖 - 后端 - 掘金JVM 1. 內(nèi)存模型( 內(nèi)存分為幾部分? 堆溢出、棧溢出原因及實例?線上如何排查?) 2. 類加載機制 3. 垃圾回收 Java基礎(chǔ) 什么是接口?什么是抽象...
閱讀 3814·2021-11-17 09:33
閱讀 2031·2021-10-26 09:51
閱讀 1547·2021-09-29 09:44
閱讀 1697·2019-08-30 15:55
閱讀 1458·2019-08-30 15:52
閱讀 2340·2019-08-30 15:43
閱讀 3446·2019-08-29 17:00
閱讀 2316·2019-08-29 16:23