介紹
單例模式就是確保一個類只有一個唯一的實例對象,系統(tǒng)中某些類只有一個實例是很重要的,例如,配置文件,只有一個實例,保證大家引用的是同一個配置;一些類的初始化過程很復(fù)雜,只需要初始化一次,減少資源消耗
實現(xiàn)單例模式的要點
1、構(gòu)造函數(shù)要私有化
2、類要自己創(chuàng)建這個實例
3、類要提供獲取這個實例的方法
4、防止反序列化生成多個實例
常見的幾種單例模式的實現(xiàn)方式
1、
在類加載的時候就創(chuàng)建了實例,避免的多線程同步的問題,但沒有達(dá)到懶加載的效果。
2、
在具體調(diào)用的時候才創(chuàng)建實例,實現(xiàn)了懶加載效果,也保證了多線程下的同步,代碼稍微復(fù)雜點。
3、
枚舉可以避免多線同步問題,也能防止反序列化創(chuàng)建新的對象,但是很少使用。可能是因此枚舉無法繼承或?qū)崿F(xiàn)其他的類或接口。
4、
由一個Map來存儲對象實例,使用的時候再創(chuàng)建實例對象,存到map中,下次則直接從map中獲取。也實現(xiàn)了懶加載,但是也要確保SingletonManager是唯一的,通常都是由應(yīng)用的上下文如application來管理SingletonManager對象。
單利模式在項目中的應(yīng)用
在把一個布局文件轉(zhuǎn)為視圖組件的時候,常常會實現(xiàn)這樣的實現(xiàn)
LayoutInflater.from(context).inflate(R.layout.activity_h_scrollview,null);
這里L(fēng)ayoutInflater對象的創(chuàng)建就是一種單例模式。來看下源碼的實現(xiàn):
context是一個抽象類,而他的實現(xiàn)類ContextImpl則會調(diào)用SystemServiceRegistry.getSystemService(this, name);在來看下具體實現(xiàn)
SYSTEM_SERVICE_FETCHERS:是一個靜態(tài)的HashMap,存儲ServiceFetcher,保證只有一個實例
====================衍生=======================
ServiceFetcher:從名字看是一個服務(wù)的獲取器,他的定義和實現(xiàn)都在SystemServiceRegistry類中。他是一個接口有多種實現(xiàn),分別定義不同類型的服務(wù)的獲取,比如
CachedServiceFetcher:
mServiceCache是ContextImpl對象創(chuàng)建的時候創(chuàng)建的
因此每個context實例都保存著一份service緩存
StaticServiceFetcher
mCachedInstance在保存在當(dāng)前對象中,而ServiceFetcher存在靜態(tài)的HashMap中的,一個類型只有一個對象,因此也保證的對象的唯一。
StaticApplicationContextServiceFetcher
和StaticServiceFetcher一樣,也只會有一個對象。