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