2011-09-09 84 views
1
public class FooClient { 

    private Foo foo; 
    private final static String key = "<api-key>"; 

    private static FooClient client = new FooClient(); 

    private FooClient() { 
     foo = new Foo(key); 
    } 

    public static FooClient getFooClient() { 
     return client; 
    } 
} 
  1. 是否確定以上述方式初始化client
  2. 我應該聲明私人Foo foo;作爲靜態的,我猜測它不是這種情況。
  3. 如果我必須爲不同的密鑰支持不同的單身人士,我應該修改getFooClient(String key)以取得密鑰並將其緩存,以便我可以返回關鍵特定的單身人士FooClients。
+1

請停止使用單身。它讓可怕的課程測試。 http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons你並不需要它們。 – zengr

+0

如果可以,遠離單身人士。從長遠來看,他們很可能會造成問題。 '新FooClient(關鍵)'是恕我直言的路要走。 – Matt

回答

4
  1. 是的。在構造函數中,你可以檢查是否client != null,如果是 - 拋出一個錯誤。 (這將對抗反射實例)

  2. 不,這是單身

  3. 是一個實例字段。你應該有一個Map<String, Foo>。但請注意,這不是「不同的單身人士」 - 你的單身人士是「客戶」。其他類可以多次實例化。

+0

[1]不清楚,你能提供它需要看的代碼片段,以及爲什麼你認爲它有問題。 – Jason

+0

如果'(client!= null)拋出新的錯誤(「嘗試第二個實例化)」,它可能會有問題,因爲可以實例化對象,即使它們的構造函數是私有的 - 通過反射 – Bozho

2

通常聲明

private static final FooClient client = new FooClient(); 

這是traditional Singleton implementation。有關其他實施選項,請參閱wikipedia page。我不會將Foo foo聲明爲static

如果你的單例可以根據鍵返回不同的實例,那麼傳遞getFooClient()方法中的鍵值是個好主意。

+0

+1這個單例可以工作95%的時間。對於剩下的5%,您需要使用volatile重複檢查鎖定。 – zengr

1

如果你有不止一個東西,它不是一個單身人士。

我會在兩種情況下使用enum

對於這只是一個的情況。

enum FooClient { 
    INSTANCE; 

    private final Foo foo = new Foo("<api-key>"); 
} 

對於不止一個的情況。

enum FooClient { 
    INSTANCE1("<api-key>"), INSTANCE2("<api-key2>"); 

    private final Foo foo; 
    FooClient(String apiKey) { 
     foo = new Foo(apiKey); 
    } 
}