常见的设计模式--单例模式
設計模式
??設計模式(Design Pattern)是一套被反復使用、多數人知曉的、經過分類的、代碼設計經驗的總結。使用設計模式的目的是為了代碼可重用性、讓代碼更容易被他人理去解、保證代碼可靠性。 設計模式使代碼編寫真正工程化;設計模式是軟件工程的基石脈絡,如同大廈的結構一樣。
單例模式
??一個類只能創建一個對象,即單例模式,該模式可以保證系統中該類只有一個實例,并提供一個訪問它的全局訪問點,該實例被所有程序模塊共享。比如在某個服務器程序中,該服務器的配置信息存放在一個文件中,這些配置數據由一個單例對象統一讀取,然后服務進程中的其他對象再通過這個單例對象獲取這些配置信息,這種方式簡化了在復雜環境下的配置管理。
餓漢模式
??餓漢模式就是在程序運行之前將所有的資源一次性創建好,在之后用的時候就會很方便。由于靜態的變量是在進入主函數之前就創建好了,所以要定義一個靜態變量,然后將構造函數和拷貝構造設置為私有的,拷貝構造函數要只聲明不定義,并在類中給出一個創建對象的靜態方法,這個靜態方法只能是引用返回,如果值返回,就會調用拷貝構造,但是拷貝構造調不了,即使可以調就會創建一個對象,這樣就和單例模式相沖突。雖然這種方式在程序運行之后不用再去創建資源,直接調用就可以,但是如果這份資源很大,那么程序就會啟動的很慢。
class Singleton { public:static Singleton* GetInstance(){return &p;}private://構造函數私有Singleton(){}//防止被拷貝Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete; private:static Singleton p; };Singleton Singleton::p;??使用場景
??在多線程高并發環境下頻繁使用,性能要求較高,那么顯然使用餓漢模式來避免資源競
爭,提高響應速度更好。
懶漢模式
??實現過程:
??懶漢模式就是在需要的時候才會去創建 構造函數和拷貝構造函數都要設為私有的,同樣的在類中給出一個創建靜態的方法,并且在類中創建一個靜態的指針,在調用這個方法時如果這個靜態的指針是空的,就為這個指針new一個對象,返回去。如果是在多線程的環境中,就會出現多個線程同時去申請資源,這時候就要多線程中常用的加解鎖操作,如果每次都要先加鎖在檢測,這時候所有的線程都會阻塞在加鎖這里,等解鎖后才可以繼續操作,所以使用DCL雙檢鎖,這時如果有一個線程在進行加解鎖操作,另一個線程也過來了,這時候資源已經申請好了,這個后來的線程就可以直接返回,不用阻塞等待之前的線程。但是這樣的版本仍然是有問題的,如果線程A正在進行對象的的創建,線程B過來了,但是A現在只是申請了空間,還沒有進行實例化,但是B檢測到這個對象不為空,直接返回去使用,就會出問題,所以要將靜態對象加一個volatile來限定一下,告訴系統每次取變量里面的信息的時候不要從寄存器中取,要到內存里面取,這樣就禁止了編譯器對創建對象的次序進行優化(申請空間->構造對象->賦值—>申請空間->賦值->構造對象)。雖然改進了這么多,但是這個代碼還存在問題,那就是沒有釋放空間,可能會存在內存泄漏。如果要釋放,就要保證所有的線程已經用完了這份資源,但是不能在類中直接給出一個靜態的釋放函數,這樣有可能會忘記調用這個函數,最好的方法就是內嵌一個內部類來實現釋放。
??使用場景
??如果單例對象構造十分耗時或者占用很多資源,比如加載插件啊, 初始化網絡連接啊,讀取文件啊等等,而有可能該對象程序運行時不會用到,那么也要在程序一開始就進行初始化,就會導致程序啟動時非常的緩慢。 所以這種情況使用懶漢模式(延遲加載)更好。
總結
以上是生活随笔為你收集整理的常见的设计模式--单例模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多变量线性回归
- 下一篇: 【每日SQL打卡】