Question

I always read singleton pattern is an anti pattern etc. But I spent nearly a day to find out, that a class had something like a cyclic dependency in construction leading to more than one object, where only one was allowed for the application. That's why I want to verify this never happens again and don't know how to do that without the singleton pattern.

public class Application {
    private SingletonModule module;

    public void getModule() {
        if(module == null) {
            module = new SingletonModule(getDependency());
        }
        return module;
    }

    private Dependency getDependency() {
        return new Dependency(getModule());
    }


}

public class Dependency {
    public Dependency(SingletonModule module) {
        System.out.println(module.getAttribute()); // is more complex of course...
    }
}

public class SingletonModule {
    public Dependency dep;
    public String attribute;

    public SingletonModule(Dependency dep) {
        this.dep=dep;
    }

    public String getAttribute() {
        return attribute;
    }

}

No the problem is getModule() is called from outside, i.e.

public class Runner {
     public Runner() {
         Application app = new Application();
         app.getModule().getAttribute();
     }
}
Was it helpful?

Solution

The constructor can check:

public class OnlyOne {
    static count = 0;
    public OnlyOne() {
        if (count > 0) throw ...
        count++;
        ...
    }
}

or a factory method:

public class OnlyOne {
    static count = 0;
    public static OnlyOne make() {
        if (count > 0) throw ...
        count++;
        return new OnlyOne();
    }
    private OnlyOne() { ...}
}

Update: Ideally, creation of this class would be so simple, e.g., when program starts and then passed as dependency, that this check would unnecessary. But if creation happens in a more complex situation, as I assume yours is, then it's a useful safety check.

OTHER TIPS

There is nothing wrong with singletons if that's what your application calls for. Static variables exist for a reason. If someone is demanding you do this in an OO way you can make them look ridiculous by creating an object called NotASingletonChecker that performs sixteen checks on a 1-variable-long array, pushing and popping instances of your "NotASingleton" class to it. Make sure you do extensive garbage collection with a "NotSingletonGarbageCollector" class.

Singleton is not an "anti-pattern". I find this word too...strong.

It is a design pattern as others.
The point is just that it could lead to a very bad practice when overused, for those reasons.
That's why a lot of good developers avoid it when they aren't forced to use it.

The antipattern would be especially to prevent a natural class (whose constructor is reachable) to spawn more than one object.

Just make use of the singleton when it makes sense, and in this case...it would.

My preferred solution would be (I imagine you may use Spring..or Guice etc...) to instantiate a bean as singleton. That way, you will end up with a perfect singleton without all these constraints of testing etc.. since your class would appear as a perfect non-singleton-designed class.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top