2
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. Is it ok to initialize client in the above fashion.
  2. Should I declare private Foo foo; as static, I am guessing its not the case.
  3. If I have to support different singletons for different keys, should I modify getFooClient(String key) to take in a key and cache it, so that I can return singleton FooClients which are key specific.
Jason
  • 10,907
  • 18
  • 45
  • 66
  • 1
    Please stop using singletons. It makes horrible classes to test. http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons You don't really need them. – zengr Sep 09 '11 at 07:09
  • If you can, stay away from singletons. They will most likely cause problems in the long run. ´new FooClient(key)´ is IMHO the way to go. – Matt Sep 09 '11 at 07:18

3 Answers3

4
  1. Yes. In the constructor you can check if client != null and if it is - throw an error. (this will counter reflection instantiations)

  2. No, it is an instance field of the singleton

  3. Yes. And you should have a Map<String, Foo>. But note that that is not "different singletons" - your singleton is the "client". The other classes can be instantiated multiple times.

Bozho
  • 554,002
  • 136
  • 1,025
  • 1,121
  • [1] is not clear, can you provide the code snippet of how it needs to look and why you think of it as problematic. – Jason Sep 09 '11 at 07:38
  • if `(client != null) throw new Error("attempted second instantiation)`. It can be problematic because one can instantiate objects even if their constructor is private - through reflection – Bozho Sep 09 '11 at 07:51
2

Usually you declare

private static final FooClient client = new FooClient();

This is the traditional Singleton implementation. See wikipedia page for other implementation options.

I would not declare Foo foo as static.

If your singleton can return different instances based on the key, then it's a good idea to pass the key value in the getFooClient() method.

MarcoS
  • 12,788
  • 5
  • 36
  • 61
  • +1 That singleton works 95% of the times. For the rest 5% you need double-check locking with volatile. – zengr Sep 09 '11 at 07:07
1

If you have more than one of something, its not a singleton.

I would use enum in both cases.

For the case where this is just one.

enum FooClient {
    INSTANCE;

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

for the case where there is more than one.

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

    private final Foo foo;
    FooClient(String apiKey) {
        foo = new Foo(apiKey);
    }
}
Peter Lawrey
  • 498,481
  • 72
  • 700
  • 1,075