android源碼之單列

模式的定義:
確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例。

使用場景
確保某個類有且只有一個對象的場景。

UML類圖
這裏寫圖片描述

簡單示例:
單例模式是設計模式中最簡單的,只有一個單例類,沒有其他的層次結構與抽象。該模式需要確保該類只能生成一個對象,通常是該類需要消耗太多的資源或者沒有沒有多個實例的理由。例如一個公司只有一個CEO、一臺電腦通常只有一個顯示器等。下面我們以公司裏的CEO爲例來簡單演示一下,一個公司可以有幾個VP,無數個員工,但是CEO只有一個,請看下面的實現代理 :
package com.dp.example.singleton;
/**
* 人的基類
* @author mrsimple
*
*/
public abstract class Person {
public abstract void talk() ;
}

// 普通員工
public class Staff extends Person {

@Override  
public void talk() {  

}  

}

// 副總裁
public class VP extends Person {

@Override  
public void talk() {  

}  

}

// CEO, 單例模式
public class CEO extends Person {

private static final CEO mCeo = new CEO();  

private CEO() {  
}  

public static CEO getCeo() {  
    return mCeo;  
}  

@Override  
public void talk() {  
    System.out.println("CEO發表講話");  
}  

}

// 公司類
import java.util.ArrayList;
import java.util.List;

public class Company {
private List allPersons = new ArrayList();

public void addStaff(Person per) {  
    allPersons.add(per);  
}  

public void showAllStaffs() {  
    for (Person per : allPersons) {  
        System.out.println("Obj : " + per.toString());  
    }  
}  

}

// test
public class Test {
public static void main(String[] args) {
Company cp = new Company() ;
Person ceo1 = CEO.getCeo() ;
Person ceo2 = CEO.getCeo() ;
cp.addStaff(ceo1);
cp.addStaff(ceo2);

    Person vp1 = new VP() ;  
    Person vp2 = new VP() ;  

    Person staff1 = new Staff() ;  
    Person staff2 = new Staff() ;  
    Person staff3 = new Staff() ;  

    cp.addStaff(vp1);  
    cp.addStaff(vp2);  
    cp.addStaff(staff1);  
    cp.addStaff(staff2);  
    cp.addStaff(staff3);  

    cp.showAllStaffs();  
}  

}

單列模式的幾種實現方法:
package com.dp.example.singleton;

public class Singleton {
private static Singleton mInstance = null;

private Singleton() {  

}  

public void doSomething() {  
    System.out.println("do sth.");  
}  

/** 
 * 方式二、double-check, 避免併發時創建了多個實例, 該方式不能完全避免併發帶來的破壞. 
 *  
 * @return 
 */  
public static Singleton getInstance() {  
    if (mInstance == null) {  
        synchronized (Singleton.class) {  
            if (mInstance == null) {  
                mInstance = new Singleton();  
            }  
        }  
    }  
    return mInstance;  
}  

/** 
 * 方式三 : 在第一次加載SingletonHolder時初始化一次mOnlyInstance對象, 保證唯一性, 也延遲了單例的實例化, 
 * 如果該單例比較耗資源可以使用這種模式. 
 *  
 * @return 
 */  
public static Singleton getInstanceFromHolder() {  
    return SingletonHolder.mOnlyInstance;  
}  

/** 
 * 靜態內部類 
 *  
 * @author mrsimple 
 * 
 */  
private static class SingletonHolder {  
    private static final Singleton mOnlyInstance = new Singleton();  
}  

/** 
 *  方式四 : 枚舉單例, 線程安全 
 * @author mrsimple 
 * 
 */  
enum SingletonEnum {  
    INSTANCE;  
    public void doSomething() {  
        System.out.println("do sth.");  
    }  
}  

/** 
 * 方式五 : 註冊到容器, 根據key獲取對象.一般都會有多種相同屬性類型的對象會註冊到一個map中 
 * instance容器 
 */  
private static Map<string singleton=""> objMap = new HashMap<string singleton="">();  
/** 
 * 註冊對象到map中 
 * @param key 
 * @param instance 
 */  
public static void registerService(String key, Singleton instance) {  
    if (!objMap.containsKey(key) ) {  
        objMap.put(key, instance) ;  
    }  
}  

/** 
 * 根據key獲取對象 
 * @param key 
 * @return 
 */  
public static Singleton getService(String key) {  
    return objMap.get(key) ;  
}  

}

優點與缺點
優點 :
1、由於單例模式在內存中只有一個實例,減少了內存開支,特別是一個對象需要頻繁地創建、銷燬時,而且創建或銷燬時性能又無法優化,單例模式的優勢就非常明顯。
2、由於單例模式只生成一個實例,所以減少了系統的性能開銷,當一個對象的產生需要比較多的資源時,如讀取配置、產生其他依賴對象時,則可以通過在應用啓動時直接產生一個單例對象,然後用永久駐留內存的方式來解決;
3、單例模式可以避免對資源的多重佔用,例如一個寫文件動作,由於只有一個實例存在內存中,避免對同一個資源文件的同時寫操作。
4、單例模式可以在系統設置全局的訪問點,優化和共享資源訪問,例如可以設計一個單例類,負責所有數據表的映射處理。

缺點 :
1、單例模式一般沒有接口,擴展很困難,若要擴展,除了修改代碼基本上沒有第二種途徑可以實現。
2、單例模式與單一職責原則有衝突。

發佈了21 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章