什麼是單例模式?
用於確保一個類在系統中有一個實例.並負責自行實例化和向整個系統提供該實例的訪問.
為什麼要使用單例模式?
在面向對象編程中有這麼兩種情況:
1 在大部分情況下,我們程序員會把類的構造器定義成public訪問權限,這樣的話就可以循序任何類來創建該類的對象.
2 在一些特殊的時候,允許其他類來自由的創建該類沒有任何意義,甚至是帶來一些負面的影響,畢竟創建一個對象會帶來相關的成本,系統開銷.例如一個系統可能隻會有一個窗口管理器,有再多的窗口管理器也是多餘的.
所以我們需要一個類隻能創建一個實例,並且此類提供一個訪問它的公共的訪問點.這便是單例模式.
如何使用單例模式?
單例模式中有以下三個特點:
靜態的私有變量.
私有的構造方法.
公共的靜態入口方法.
如果理解上面的三個特點,那麼整個單例模式的框架就描繪出來瞭.
那為什麼單例模式會有上面三個特點?
第一個特點:靜態私有變量.因為該類必須緩存已經創建的對象,否則的話該類根本不知道是否創建過對象,也就無法保證隻能創建一個對象,所以此類需要使用一個屬性來保存曾經創建過的對象,而此屬性需要被此類中的一個靜態方法訪問,所以這個屬性必須使用static來進行修飾.
第二個特點:私有的構造方法.因為單例模式要求此類不能夠被其他類創建對象,而隻能允許該類創建一個對象,所以為瞭避免其他類來自由的創建此類的實例,我們就通過把該類的構造器使用private來修飾,從而將該類的構造器隱藏起來,其他類便不能創建該類的對象.
第三個特點:公共的靜態入口方法.根據良好的封裝原則,一旦該類的構造器被隱藏,則需要提供一個public方法作為該類的訪問點,用於創建該類的對象,且方法必須使用static進行修飾,為什麼呢,因為你在調用這個方法的時候不存在該類的對象,也就是說調用該方法的不可能是對象,隻能是類,所用需要用static進行修飾.
以上的三個特點便是單例模式的核心點.下面則通過單例模式的代碼來進行展示整個單例模式的過程:
單例類:Singleton
[java]
/**
* 簡單的單例模式
* @author jnqqls
*
*/
publicclass Singleton {
//使用靜態變量來緩存創建的實例.
private static Singleton instance = null;
//用private,隱藏構造器.
privateSingleton(){
}
//提供靜態方法,用來返回Singleton實例.
//加入控制,保證隻有一個實例.
publicstatic Singleton getInstance(){
if(instance == null){
//創建一個Singleton對象,並保存在instance中.
instance= new Singleton();
}
returninstance;
}
}
客戶端:TestSingleton
[java]
/**
* 客戶端程序,查看單例模式的效果.
* @author jnqqls
*
*/
publicclass TestSingleton {
/**
* @param args
*/
publicstatic void main(String[] args) {
//實例化第一個單例對象
SingletoninstanceOne = Singleton.getInstance();
//實例化第二個單例對象
SingletoninstanceTwo = Singleton.getInstance();
//查看兩個實例是否是同一個對象?
System.out.println(instanceOne.equals(instanceOne));
System.out.println(instanceOne==instanceTwo);
}
}
輸出結果:
true
true
通過上面的代碼可以看出我們可以通過方法進行自定義控制,保證Singleton類隻有一個實例,所以從最後的運行結果可以看到在TestSingleton類的main方法中所產生的兩個對象其實是同一個對象.
那麼在什麼場景下適合用單例模式呢?
如果這個類中沒有可以修改的成員變量,也就是說這個類沒有狀態,如果存在可以修改成員變量的話就會產生線程安全的問題,所以不建議使用.因為單例模式無法繼承,所以也沒有辦法擴展,無法擴展其實現.比較適合單例模式是在讀取配置文件的場景.
在接下來的文章將會介紹如何通過單例模式來讀取配置文件.