這是咱們最多見的一類模式,對這一類模式有一個通用的特色就是:java
封裝建立的方式和過程。android
這裏所謂封裝就是隱藏的意思,對對象的建立方法和過程不可見,或者是虛擬的過程。spring
隱藏建立方式,就是如單例,工廠方法,隱藏建立過程則是指builder,原型,至於抽象工廠,我認爲他包含了以上兩種。數據庫
咱們想一想一個對象的建立有哪些步驟?ide
1,建立什麼東西?--接口定義ui
2,誰建立? --決策類or幫助類this
3,如何建立? --how,建立過程idea
4,何時建立? --建立時機的觸發
code
由此可知,建立型就是在上面幾個點作文章xml
我將單例模式放在最前面來說,是由於簡單和直白。
1,單例模式
gof原文這麼講的:"Ensure a class only has one instance, and providea global point of access to it"
有2點:
a,僅且只能有1個實例
b,提供一個全局訪問點
就是說一個對象只能生成一次,而後能夠全局個方法或者類去調用。
<有事離開,未完待續>
從上面描述就知道,咱們通常在須要只用對象的一個實例的時候纔用到這個模式,相似咱們常說的全局對象,在j2ee中咱們知道默認spring初始化bean的時候都是單例的,咱們也能夠在配置文件中定義,以下:
<bean id="foo" class="foo" singleton="true" />
這告訴spring容器,foo的實例只會生成一次。
那麼在android中,有哪些地方用到了單例模式呢?
咱們知道一個手機中,打開輸入法,無論在哪打開,其實都是一個實例;Activity.java中有一個mSearchManager的對象它也是單例對象;若是是android原生系統,有個全局搜索global,若是看android源碼,你會發現DisplayManagerGlobal,WindowManagerGlobal等等不少都是單例的,這些對象負責管理整個手機的運行處理。咱們來看 WindowManagerGlobal 的實現:
public static WindowManagerGlobal getInstance() { synchronized (WindowManagerGlobal.class) { if (sDefaultWindowManager == null) { sDefaultWindowManager = new WindowManagerGlobal(); } return sDefaultWindowManager; } }
這樣系統保證了WindowManagerGlobal 對象的產生只會有一個,在系統調用(決策對象)須要的時候,調用getInstance(全局訪問點),來生成new 。這是一個很完整的單例模式的實現,一個很好的例子。
mSearchManager的實現也頗有意思:
private void ensureSearchManager() { if (mSearchManager != null) { return; } mSearchManager = new SearchManager(this, null); }
這裏有人會說怎麼這樣嗯,沒返回SearchManager對象啊,就是沒有決策類這個角色。其實他是有的,他的決策類就是咱們經常使用的getSystemService,看代碼:
@Override public Object getSystemService(String name) { if (getBaseContext() == null) { throw new IllegalStateException( "System services not available to Activities before onCreate()"); } if (WINDOW_SERVICE.equals(name)) { return mWindowManager; } else if (SEARCH_SERVICE.equals(name)) { ensureSearchManager(); return mSearchManager; } return super.getSystemService(name); }
其實這裏getSystemService咱們能夠看作一個特殊的決策類,從如下代碼來看:
if (SEARCH_SERVICE.equals(name)) { ensureSearchManager(); return mSearchManager; }
咱們改爲:
public static SearchManager getInstance(){ ensureSearchManager(); return mSearchManager; }
這就是一個單例模式。但從getSystemService整個代碼來看,確實工廠方法模式,這個咱們在下面會講到。
根據對象建立時機的不一樣,單例模式有三種方式:
1,,餓漢式 --就是實例在類加載的時候就生成
public class foo{ foo(){} private static foo instance =new foo(); public static foo getlnstance(){ return instance; } }
2,懶漢式
public class foo{ foo(){} private static foo instance = null ; public static foo getlnstance(){ if(instance == null){ instance = new foo(); } return instance; } }
3,註冊式
public static foo getInstance(String name) { if(name == null) { name = foo .class.getName(); System.out.println("name == null"+"--->name="+name); } if(map.get(name) == null) { try { map.put(name, (foo ) Class.forName(name).newInstance()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } return map.get(name); }
第一種和第二種方式區別在於建立時機的差別,而第三種則是如何建立有區別。
最後,問幾個問題:
1,android還有哪些其餘的單例模式
2,launcher mode中有沒有單例模式的實現
3,單例模式的拓展中,數據庫鏈接池屬於哪一種方式的變異(衍生).
4,三種方式的單例模式的優缺點有哪些?通常用途區別在哪?。