Java Reference
In-Depth Information
of singleton to provide several instances of a class. Most often, the implementation
defines a private constructor and a static variable. For example, the simplest singleton
implementation is
public class Singleton {
public static final Singleton INSTANCE = new Singleton();
private Singleton() {}
}
Here, you access the singleton with the static final field INSTANCE . Alternatively, the
class can use lazy initialization to create the instance, for example:
public class Singleton {
private static Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if(INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
The Singleton design pattern needs to make sure the object is instantiated only once.
To ensure this, we hide the constructor by making it private . As with a private
method, you can't call and test a private constructor explicitly. You have a choice: you
can rely on code coverage to check that all private methods are tested, or you change
access modifiers to open the class to explicit testing of those methods.
The obvious drawback of a singleton is that it introduces global state into your
application. The INSTANCE field in the first example is a global variable. Use this design
pattern with care.
5.2.7
Favor generic methods
Static methods, like factory methods, are useful, but large groups of utility static
methods can introduce issues of their own. Recall that unit testing is testing in isola-
tion. In order to achieve isolation you need some articulation points in your code,
where you can easily substitute your code with the test code. These points use poly-
morphism. With polymorphism (the ability of one object to appear as another object)
the method you're calling isn't determined at compile time. You can easily use poly-
morphism to substitute application code with the test code to force certain code pat-
terns to be tested.
The opposite situation occurs when you use nothing but static methods. Then you
practice procedural programming, and all of your method calls are determined at
compile time. You no longer have articulation points that you can substitute.
Sometimes the harm of static methods to your test isn't big, especially when you
choose some method that ends the execution graph, like Math.sqrt() . On the other
hand, you can choose a method that lies in the heart of your application logic. In
 
 
 
 
Search WWH ::




Custom Search