android設計模式之單例模式詳解
這是我們最常見的一類模式,對這一類模式有一個通用的特點就是:
封裝創(chuàng)建的方式和過程。
這里所謂封裝就是隱藏的意思,對對象的創(chuàng)建方法和過程不可見,或者是虛擬的過程。
隱藏創(chuàng)建方式,就是如單例,工廠方法,隱藏創(chuàng)建過程則是指builder,原型,至于抽象工廠,我認為他包含了以上兩種。
我們想想一個對象的創(chuàng)建有哪些步驟?
1、創(chuàng)建什么東西?--接口定義
2、誰創(chuàng)建? --決策類or幫助類
3、如何創(chuàng)建? --how,創(chuàng)建過程
4、什么時候創(chuàng)建? --創(chuàng)建時機的觸發(fā)
由此可知,創(chuàng)建型就是在上面幾個點做文章
我將單例模式放在最前面來講,是因為簡單和直白。
1、單例模式
gof原文這么講的:
Ensure a class only has one instance, and providea global point of access to it
有2點:
a、僅且只能有1個實例
b、提供一個全局訪問點
就是說一個對象只能生成一次,然后可以全局個方法或者類去調用。
<有事離開,未完待續(xù)>
從上面描述就知道,我們一般在需要只用對象的一個實例的時候才用到這個模式,類似我們常說的全局對象,在j2ee中我們知道默認spring初始化bean的時候都是單例的,我們也可以在配置文件中定義,如下:
<bean id="foo" class="foo" singleton="true" />
這告訴spring容器,foo的實例只會生成一次。
那么在android中,有哪些地方用到了單例模式呢?
我們知道一個手機中,打開輸入法,不管在哪打開,其實都是一個實例;Activity.java中有一個mSearchManager的對象它也是單例對象;如果是android原生系統,有個全局搜索global,如果看android源碼,你會發(fā)現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整個代碼來看,確實工廠方法模式,這個我們在下面會講到。
根據對象創(chuàng)建時機的不同,單例模式有三種方式:
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);
}
第一種和第二種方式區(qū)別在于創(chuàng)建時機的差異,而第三種則是如何創(chuàng)建有區(qū)別。
最后,問幾個問題:
1、android還有哪些其他的單例模式
2、launcher mode中有沒有單例模式的實現
3、單例模式的拓展中,數據庫連接池屬于哪種方式的變異(衍生).
4、三種方式的單例模式的優(yōu)缺點有哪些?一般用途區(qū)別在哪?。
相關文章
Android ScrollView 下嵌套 ListView 或 GridView出現問題解決辦法
這篇文章主要介紹了ScrollView 下嵌套 ListView 或 GridView 會發(fā)列表現數據只能顯示一行。因為他們都是滾動結構,兩個滾動條放到一起就會引起沖突,這里提供解決辦法相關資料,需要的朋友可以參考下2017-07-07
Android自定義View實現簡單的圓形Progress效果
這篇文章主要介紹了Android自定義View實現簡單的圓形Progress效果的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-09-09

