2013-04-02 22 views
3

我有一個類將作爲單身人士。
該類將獲得一個文件作爲構造函數的一部分。之後,班級準備好了。
因此,目前我使用雙重檢查鎖定成語,並通過static getInstance()即經典方式獲得單身人士的實例。
我的問題是,目前我做不斷:我該如何改進這個單身人士?

MySingleton.getInstance(theFile);

而且theFile只需要在單身構造的第一次。之後,即一旦建立了單身人士,我不需要通過theFile
我該怎麼做?
我想創建一個MySingleton.getInstance();,但仍然不行,因爲調用者必須第一次調用MySingleton.getInstance(theFile);構造一個有效的類。
我怎樣才能更好地設計這個?

回答

9

聲明一個init()方法使用文件來處理初始化。

簡化getInstance()返回實例,但如果還沒有調用init(),則拋出IllegalStateException

例如:

public class MySingleton { 

    private MySingleton INSTANCE; 

    // private constructor is best practice for a singleton 
    private MySingleton(File theFile) { 
     // initialize class using "theFile" 
    } 

    public static void init(File theFile) { 
     // if init previously called, throw IllegalStateException 
     if (INSTANCE != null) 
      throw new IllegalStateException(); 
     // initialize singleton 
     INSTANCE = new MySingleton(theFile); 
    } 

    public static MySingleton getInstance() { 
     // if init hasn't been called yet, throw IllegalStateException 
     if (INSTANCE == null) 
      throw new IllegalStateException(); 
     return INSTANCE; 
    } 

    // rest of class 
} 

注意,雖然這不是線程安全的,競爭條件是少數確實,如果有的話,只要init()及早稱爲服務器啓動的一部分。

+1

@ sp00m感謝您的編輯。我在iPhone上輸入了這個信息:/ – Bohemian

+1

我在開玩笑吧。你在iPhone上鍵入完整的代碼!感謝您的熱心貢獻.. –

1

也許你可以提供一種方法來初始化一個單例。您可以定義一個稱爲initialize()的靜態方法,它接受文件並創建一個單例對象 - 在應用程序啓動時或在適當的位置。之後,您可以使用getInstance()。

0

你可以簡單地具有不具有文件參數getInstance()方法。

它會拋出一個異常,如果它在另一個之前被調用,但這是好的,因爲無論如何你只能避免傳遞文件,如果你已經確認單是之前創建的。

3

在一個典型的依賴注入的環境中,你的文件的名稱將是一個屬性對應於該單例類的singleton的bean,用範圍,因爲單。然後你只需要在需要它的任何類中注入這個bean。

如果你的程序沒有DI容器,那麼這個文件名應該是作爲JVM參數/通過某些屬性文件獲取的應用程序級屬性,或者是最差情況下的單個類中的常量。客戶端不應該擔心這個單例類使用的文件。

0

init()方法+異常的替代,

Singleton::getInstance().load(myFile)

只要確保這是在啓動時完成/不管。

0

的另一種方法首先是singletone with parameter is not a singletone的。

爲了解決這個問題,你有兩個選擇,第一個是在上面的鏈接中描述的,第二個是從裏面獲取資源。

該文件通常與路徑相關聯,您可以從應用程序啓動期間通過/設置的某種屬性存儲訪問該路徑。

可能實施這樣的機制:

public enum MySingleton { 
INSTANCE; 

private final File theFiel; 

private MySingleton() { 
    this.theFile = initialize(MySystemProperties.getValue(MySystemProperties.MY_SINGLETONE_PATH); 

} 

private File initialize(String path) { 
    reutrn new File(path); // 

} 

} 
0

的唯一辦法優化它是通過不使用Singleton模式的。

說真的。你正在拍攝自己的腳。

每當您開始將未使用的值傳遞給方法時,應該有真的響亮的警鐘響起,提醒您在丹麥狀態下某種結構上已經腐爛。顯然,你可以選擇忽略這些警鐘(也可能是這個答案),但它不會讓你的代碼更少。我知道,我在這裏是個吝嗇鬼。 但事實上,使用單身人士會將您的程序變成大量的熱氣騰騰的spaghettizzle。

There are | huge amounts | of posts | on why | singletons suck | more ass | than a | leech on | a donkey

因爲我不知道你想用這個班級實現什麼目標,所以我不幸提供了一個解決方案。

除了這個:不要使用單身。

稍後你會感謝我。 它看起來很難,它會需要大量的閱讀和試​​驗,但編碼正確會讓你感覺好多了。並且會讓你變成一個更好的程序員。