Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>A Singleton, by definition, has exactly one instance. Hence its creation is strictly controlled by the class itself. Typically it is a concrete class, not an interface, and due to its private constructor it is not subclassable. Moreover, it is found actively by its clients (by calling <code>Singleton.getInstance()</code> or an equivalent), so you can't easily use e.g. <a href="http://en.wikipedia.org/wiki/Dependency_injection" rel="noreferrer">Dependency Injection</a> to replace its "real" instance with a mock instance:</p> <pre><code>class Singleton { private static final myInstance = new Singleton(); public static Singleton getInstance () { return myInstance; } private Singleton() { ... } // public methods } class Client { public doSomething() { Singleton singleton = Singleton.getInstance(); // use the singleton } } </code></pre> <p>For mocks, you would ideally need an interface which can be freely subclassed, and whose concrete implementation is provided to its client(s) by dependency injection.</p> <p>You can relax the Singleton implementation to make it testable by </p> <ul> <li>providing an interface which can be implemented by a mock subclass as well as the "real" one</li> <li>adding a <code>setInstance</code> method to allow replacing the instance in unit tests</li> </ul> <p>Example:</p> <pre><code>interface Singleton { private static final myInstance; public static Singleton getInstance() { return myInstance; } public static void setInstance(Singleton newInstance) { myInstance = newInstance; } // public method declarations } // Used in production class RealSingleton implements Singleton { // public methods } // Used in unit tests class FakeSingleton implements Singleton { // public methods } class ClientTest { private Singleton testSingleton = new FakeSingleton(); @Test public void test() { Singleton.setSingleton(testSingleton); client.doSomething(); // ... } } </code></pre> <p>As you see, you can only make your Singleton-using code unit testable by compromising the "cleanness" of the Singleton. In the end, it is best not to use it at all if you can avoid it.</p> <p><strong>Update:</strong> And here is the obligatory reference to <a href="http://rads.stackoverflow.com/amzn/click/0131177052" rel="noreferrer">Working Effectively With Legacy Code</a> by Michael Feathers.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload