Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a class singleton without using static method

I need to create a singleton class without keeping a static method.

How can i do that?

like image 318
Sunny Gupta Avatar asked Dec 22 '11 10:12

Sunny Gupta


2 Answers

Create an enum with one instance

enum Singleton {
    INSTANCE;

    private Field field = VALUE;
    public Value method(Arg arg) { /* some code */ }
}

// You can use
Value v = Singleton.INSTANCE.method(arg);

EDIT: The Java Enum Tutorial shows you how to add fields and methods to an enum.


BTW: Often when you can use a Singleton, you don't really need one as utility class will do the same thing. The even shorter version is just

enum Utility {;
    private static Field field = VALUE;
    public static Value method(Arg arg) { /* some code */ }
}

// You can use
Value v = Utility.method(arg);

Where Singletons are useful is when they implement an interface. This is especially useful for testing when you using Dependency injection. (One of the weakness of using a Singleton or utility class substitution in unit tests)

e.g.

interface TimeService {
    public long currentTimeMS();
}

// used when running the program in production.
enum VanillaTimeService implements TimeService {
    INSTANCE;
    public long currentTimeMS() { return System.currentTimeMS(); }
}

// used in testing.
class FixedTimeService implements TimeService {
    private long currentTimeMS = 0;
    public void currentTimeMS(long currentTimeMS) { this.currentTimeMS = currentTimeMS; }
    public long currentTimeMS() { return currentTimeMS; }
}

As you can see, if your code uses TimeService everywhere, you can inject either the VanillaTimeService.INSTANCE or a new FixedTimeService() where you can control the time externally i.e. your time stamps will be the same every time you run the test.

In short, if you don't need your singleton to implement an interface, all you might need is a utility class.

like image 111
Peter Lawrey Avatar answered Nov 15 '22 16:11

Peter Lawrey


public class Singleton {
    public static final Singleton instance = new Singleton();
    private Singleton() {}
    public void foo() {}
}

then use

Singleton.instance.foo();
like image 24
andrey Avatar answered Nov 15 '22 17:11

andrey