Android設(shè)計(jì)模式之單例模式解析
在日常開發(fā)過程中時(shí)常需要用到設(shè)計(jì)模式,但是設(shè)計(jì)模式有23種,如何將這些設(shè)計(jì)模式了然于胸并且能在實(shí)際開發(fā)過程中應(yīng)用得得心應(yīng)手呢?和我一起跟著《Android源碼設(shè)計(jì)模式解析與實(shí)戰(zhàn)》一書邊學(xué)邊應(yīng)用吧!
今天我們要講的是單例模式
定義
確保某一個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例
使用場景
確保某個(gè)類有且只有一個(gè)對象的場景,避免產(chǎn)生多個(gè)對象消耗過多的資源
某個(gè)類型的對象只應(yīng)該有一個(gè)
使用例子
- 應(yīng)用的Application
- 圖片加載框架對象,比如我們的ImageLoader,常用的圖片加載框架Glide,universal-image-loader等
- 數(shù)據(jù)請求管理類,比如可以用一個(gè)類來統(tǒng)一所有的數(shù)據(jù)請求處理,訪問數(shù)據(jù)庫,網(wǎng)絡(luò)請求等,這樣的類肯定只需要一個(gè)實(shí)例
實(shí)現(xiàn)
實(shí)現(xiàn)的要點(diǎn)
- 構(gòu)造函數(shù)不對外開放,必須為Private(就是不能用New的形式生成對象)
- 通過一個(gè)靜態(tài)方法或者枚舉返回單例對象
- 確保單例類的對象有且只有一個(gè),尤其是在多線程環(huán)境下
- 確保單例類對象在反序列化時(shí)不會(huì)重新創(chuàng)建對象
常見的實(shí)現(xiàn)方式
餓漢單例模式
public class Singleton {
private static final Singleton singleton = new Singleton();
//構(gòu)造函數(shù)私有化
private Singleton() {
}
//公有的靜態(tài)函數(shù),對外暴露獲取單例對象的接口
public static Singleton getInstance() {
return singleton;
}
}
餓漢單例模式采用的是靜態(tài)變量 + fianl關(guān)鍵字的方式來確保單例模式,應(yīng)用啟動(dòng)的時(shí)候就生成單例對象,效率不高
懶漢模式
public class Singleton {
private static Singleton singleton;
//構(gòu)造函數(shù)私有化
private Singleton() {
}
//公有的靜態(tài)函數(shù),對外暴露獲取單例對象的接口
public static synchronized Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
懶漢模式的主要問題在于由于加了synchronized關(guān)鍵字,每調(diào)用一次getInstance方法,都會(huì)進(jìn)行同步,造成了不必要的開銷
以上的2種模式用的都不多,了解一下就好,下面介紹平時(shí)用得比較多的單例模式
Double Check Lock(DCL)模式(雙重檢查鎖定模式)
public class Singleton {
private static Singleton singleton = null;
//構(gòu)造函數(shù)私有化
private Singleton() {
}
//公有的靜態(tài)函數(shù),對外暴露獲取單例對象的接口
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
DCL模式是使用最多的單例模式,它不僅能保證線程安全,資源利用率高,第一次執(zhí)行g(shù)etInstance時(shí)單例對象才會(huì)實(shí)例化;同時(shí),后續(xù)調(diào)用getInstance方法時(shí)又不會(huì)有懶漢模式的重復(fù)同步的問題,效率更高;在絕大多數(shù)情況下都能保證單例對象的唯一性
DCL模式的缺點(diǎn)是第一次加載時(shí)由于需要同步反應(yīng)會(huì)稍慢;在低于JDK1.5的版本里由于Java內(nèi)存模型的原因有可能會(huì)失效
靜態(tài)內(nèi)部類單例模式
public class Singleton {
private Singleton() {
}
public static Singleton getInstance() {
return SingletonHolder.sInstance;
}
//靜態(tài)內(nèi)部類
private static class SingletonHolder {
private static final Singleton sInstance = new Singleton();
}
}
第一次加載Singleton類時(shí)不會(huì)初始化sInstance,只有在第一次調(diào)用getInstance方法時(shí)才會(huì)初始化sInstance,延遲了單例對象的實(shí)例化
靜態(tài)內(nèi)部類單例模式不僅能保證線程安全也能保證單例對象的唯一性
靜態(tài)內(nèi)部類單例模式和DCL模式是推薦的單例實(shí)現(xiàn)模式
枚舉單例
public enum Singleton {
INSTANCE;
}
默認(rèn)枚舉實(shí)例的創(chuàng)建是線程安全的,并且在任何情況下它都是一個(gè)單例
其他的單例模式,在一種情況下會(huì)出現(xiàn)失效的情況——反序列化,但是枚舉即使在反序列化情況下也不會(huì)失效
總結(jié)
單例模式是運(yùn)用頻率很高的模式,由于在客戶端一般沒有高并發(fā)的情況,現(xiàn)在的JDK版本也已經(jīng)到了9了,一般推薦用DCL模式和靜態(tài)內(nèi)部類2種實(shí)現(xiàn)。
單例對象的生命周期很長,如果持有Context,很容易引發(fā)內(nèi)存泄漏,所以傳遞給單例對象的Context最好是Application Context
最后加點(diǎn)福利
單例模式的代碼格式都是固定的,每次都要那么寫有點(diǎn)麻煩,咱們可以用添加模板的方法來偷懶,詳情見圖。

添加了模板后,在需要實(shí)現(xiàn)單例模式的類里面直接輸入你的模板名字,如圖中的sin, Android Studio就會(huì)出現(xiàn)提示,回車搞定!趕緊試試吧!
源碼地址:https://github.com/snowdream1314/ImageLoader
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android異步消息處理機(jī)制實(shí)現(xiàn)原理詳解
這篇文章主要介紹了Android異步消息處理機(jī)制實(shí)現(xiàn)原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
Android基于ViewPager實(shí)現(xiàn)類似微信頁面切換效果
這篇文章主要介紹了Android基于ViewPager實(shí)現(xiàn)類似微信頁面切換效果,通過Fragment適配器實(shí)現(xiàn)頁面切換效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
Android自定義ListView實(shí)現(xiàn)仿QQ可拖拽列表功能
這篇文章主要介紹了Android自定義ListView實(shí)現(xiàn)仿QQ可拖拽列表功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-08-08
appium運(yùn)行各種坑爹報(bào)錯(cuò)問題及解決方法【推薦】
這篇文章主要介紹了 appium運(yùn)行各種坑爹報(bào)錯(cuò)問題及解決方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06
Android?AIDL通信DeadObjectException解決方法示例
這篇文章主要為大家介紹了Android?AIDL通信DeadObjectException解決的方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
Android 開發(fā)中Volley詳解及實(shí)例
這篇文章主要介紹了Android 開發(fā)中Volley詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-04-04
Android懸浮窗的實(shí)現(xiàn)(易錯(cuò)點(diǎn))
現(xiàn)在很多應(yīng)用都使用到懸浮窗,例如微信在視頻的時(shí)候,點(diǎn)擊Home鍵,視頻小窗口仍然會(huì)在屏幕上顯示。下面小編來實(shí)現(xiàn)一下android 懸浮窗,感興趣的朋友跟隨小編一起看看吧2019-10-10
android okhttp的基礎(chǔ)使用【入門推薦】
本文主要總結(jié)了Android著名網(wǎng)絡(luò)框架-okhttp的基礎(chǔ)使用。具有一定的參考價(jià)值,下面跟著小編一起來看下吧2017-01-01

