2011-09-09 72 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); 
    } 
}