0x02 - 應(yīng)用最廣的設(shè)計模式——單例模式

1、定義

單例對象的類必須保證只有一個實例存在。
確保某一個類只有一個實例,而且自行實例化并向整個系統(tǒng)提供這個實例。

2、使用場景

避免產(chǎn)生對個對象消耗過多的資源,或者某種類型的對象只應(yīng)該有且只有一個。

3、實現(xiàn)方式

  • 餓漢模式
public class CEO  {
    private static final CEO mCEO = new CEO();

    private CEO() {
    }

    public static CEO getCEO() {
        return mCEO;
    }
}
  • 懶漢模式
public class CEO  {
    private static CEO instance;

    private CEO() {
    }

    public synchronized static CEO getCEO() {
        if (instance == null) {
            instance = new CEO();
        }
        return instance;
    }
}
  • 懶漢模式 - double checkLock
public class CEO {
    private CEO() {
    }

    private static CEO instance = null;

    public static CEO getInstance() {
        //避免不必要的同步
        if (instance == null) {
            synchronized (CEO.class) {
                //同步后仍然為null,再創(chuàng)建
                if (instance == null) {
                    instance = new CEO();
                }
            }
        }
        return instance;
    }
}
  • 靜態(tài)內(nèi)部類
public class CEO {
    private CEO() {
    }

    public static CEO getInstance() {
        return CEOHolder.instance;
    }

    /**
     * 靜態(tài)內(nèi)部類
     * 確保線程安全,也能保證單例對象的唯一性
     * 延時了單例的初始化
     */
    private static class CEOHolder {
        private static final CEO instance = new CEO();
    }

    //防止反序列化時,可以通過反射來創(chuàng)建新對象
    private Object readResolve() throws ObjectStreamException {
        return getInstance();
    }
}
  • 枚舉
    默認枚舉實例的創(chuàng)建是線程安全的,并且在任何情況下它都是一個單例,包括反序列化的時候(其余的實現(xiàn)都會在反序列化時出現(xiàn)問題,靜態(tài)內(nèi)部類實現(xiàn)方式已給出解決方案 反序列化相關(guān)
public enum CEO {
    INSTANCE;
}
  • 容器
    通過統(tǒng)一的接口進行獲取操作,降低了使用成本,及耦合度
public class SingletonManager {
    private static Map<String, Object> sObjectMap = new HashMap<>();

    private SingletonManager() {
    }

    public static void registerService(String key, Object instance) {
        if (!sObjectMap.containsKey(key)) {
            sObjectMap.put(key, instance);
        }
    }

    public static Object getService(String key) {
        return sObjectMap.get(key);
    }
}

4、Demo

5、Android 源碼中的運用

android.content.Context
public final @Nullable <T> T getSystemService(@NonNull Class<T> serviceClass) 

優(yōu)缺點

  • 優(yōu)點
  1. 減少了內(nèi)存開支
  2. 減少了系統(tǒng)的性能開銷
  3. 避免對資源的多重占用
  4. 可以在系統(tǒng)設(shè)置全局的訪問點,優(yōu)化和共享資源訪問
  • 缺點
  1. 單例模式一般沒有接口,擴展性差
  2. 單例對象如果持有 Context 對象,容易引發(fā)內(nèi)存泄漏,最好使用 Application Context
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容