Singleton Pattern – Implementing Without Static Methods

object-orientedsingletonstatic methodsstatic-keyword

I heard that static (in the Java sense, basically a static method is called on the class itself and not on an instance) is not True OOP. However, how would the Singleton pattern be implemented in such a language. I thought of having an FooGetter class, and calling a getFoo() method on an instance of it, but how will the FooGetter store the instance of Foo without static variables?

Best Answer

A singleton pattern implementation such as:

public final class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

can be replaced with dependency injection. Simply construct the object once, in the static method main, and pass it to everything that needs it.

public static void main(){
    Date applicationStart = new Date();

    Uptime uptime = new Uptime(applicationStart);
    Performance performance = new Performance(applicationStart);

    //...
}

Here two objects that both need to know the application start and do not want to see the Date constructed twice are both given references to the same single object. By responsibly passing around a reference rather than fearfully preventing construction all requirements are met. This approach allows for far more flexibility since the users of the singleton are not required to know how to find it.

The drawback with this approach is it doesn't support lazy initialization.

However, this is only needed if construction of the object is expensive. Many designs avoid the problem by forbidding constructors from doing work besides validation and storing of instance variables. Generally neither is expensive enough to justify lazy initialization. The size of the object can also be a reason for lazy initialization. Good designs tend to avoid large objects. Initializing a resource and modeling it's availability with the creation of an object also may provide a reason to use lazy initialization. How much sense that makes may depend on language due to object lifetime semantics.

Lazy initialization doesn't require the singleton pattern in any case. DI combined with an single abstract factory object that also caches the object it constructs when called will also satisfy a lazy initialization requirement without hard coding clients to the construction code.

The singleton pattern is largely avoided because it solves problems that good designs don't have in the first place. But when the need arises it still works as well as it ever did. Object oriented or not.

Related Topic