模式設計是什麼?初學者一開始會被這高大上的名稱給唬住。而對於有豐富編程經驗的老鳥來說,模式設計又是無處不在。很多接觸的框架就是基於各種模式設計形成的。 簡單說,在寫代碼的過程中一開始往往接觸的是面向過程的,簡單的基礎的編程。這個時候我們往往追求的是代碼能夠實現某項功能就萬事大吉。管他代碼多麼冗余,管他代碼是否可重用,管他效率如何,能實現功能就好。但是,真正應用於實際的,更被大家采納的是那些高效的,可重用的,便於團隊開發的代碼。基於這些因素,你不能像練手一樣,隨便命名函數名,隨便放置腳本。模式設計告訴是給人們組織代碼提供一種思路,實現可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。
在所有模式設計中,有三種基礎設計模式,單例模式,工廠模式,注冊樹模式,其他模式往往基於這幾種模式,今天帶來的是單例模式。
什麼是單例模式?
根據這個名稱,我們很容易了解到,單例模式指的是在整個應用中只有一個對象實例的設計模式。
為什麼要用單例模式?
php常常和數據庫打交道,如果在應用中如果頻繁建立連接對象,進行new操作的話,會消耗大料的系統內存資源,這並不是我們希望看到的。再則,在團隊合作項目中,單例模式可以有效避免不同程序員new自己的對象,造成人為的系統消耗。
如何建立單例模式?
在看到這個問題的時候,相信優秀的程序員很可能自己試著根據要求去創建單例模式,而不是坐等前人的經驗。區別於其他博友告訴你什麼樣的模式是單例模式,我人更願意和有面向對象編程基本經驗的你考慮一下如何自己建立單例模式。
我們首先從題目出發,單例模式是只有一個對象實例的設計模式。這一點是很讓人蛋疼的。我們平常創建的類不是能創建很多對象的,就是不能創建對象的(抽象類)。要創建對象需要有類這是必須的,而且不能是抽象類。這個類要防止別人可以多次創建函數。我們自然而然考慮到了從構造函數入手。但是,每次new操作都會調用構造函數,也就是會多次創建對象實例。這和我們設計初衷相悖了。在此處務必申明構造函數為private或者protected這樣才能解決這個問題。
構造函數被申明為private或者protected這注定無法通過new的方法創建實例對象了。而且我們發現,經過這一步處理後,解決問題的前景變得明朗起來?為什麼呢?既然無法通過new方法創建對象實例,那麼我們只能通過類內的方法來創建對象實例了。 這個時候我們面臨一個有趣的先有雞還是先有蛋的問題。我們往往往往是創建了對象後才調用對象的方法,而此時需要調用類裡面的方法來創建對象。不受是否創建對象影響都能調用的方法的解決方案毋庸置疑那就是利用關鍵字--static。
在類內創建靜態方法完成完成什麼工作呢?回歸主題:確保只創建一個實例對象。如何確保只有一個呢?這很簡單,if判斷一下啊。存在的話直接返回,不存在自己創建一個嘛。當然這個實例對象是類的靜態屬性。至此,單例模式要求的功能實現完成。真的完成了麼?還不算~如果有個類繼承本類,將構造方法申明為public那不又壞事兒了?那有必要在構造方法前加final關鍵字了。
最後貼上單例模式代碼,代碼解釋都在上面了~~
<?php class Single{ public $hash; static protected $ins=null; final protected function __construct(){ $this->hash=rand(1,9999); } static public function getInstance(){ if (self::$ins instanceof self) { return self::$ins; } self::$ins=new self(); return self::$ins; } }
本身單例模式並不復雜,但需要深入理解。很多初學者依舊會感歎:臥槽,構造方法原來不一直是public啊~臥槽還可以不通過new創建對象啊~其實筆者想說,不管構造方法被申明為public,private還是protected,最終創建對象的時候都會調用。一直是new創建對象實例,單例模式也用new創建對象,只是換個地方而已,從類外到類內。
最後對研究出各種精妙的模式設計的程序員表示拜服~~
系列文章:
php模式設計之 單例模式
php模式設計之 工廠模式
php模式設計之 注冊樹模式