Showing posts with label utility class. Show all posts
Showing posts with label utility class. Show all posts

Sunday, 20 February 2011

Constant interface

Constant interface contains no methods but it consists solely of static final fields, each exporting a constant. Classes using these constants implement the interface to avoid the need to qualify constant names with a class name. Here is an example:

// Constant interface pattern - do not use!
public interface PhysicalConstants {
// Avogadro's number (1/mol)
static final double PLANCK_CONSTANT = 6.62e-34;
// Boltzmann constant (J/K)
static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
// Mass of the electron (kg)
static final double ELECTRON_MASS = 9.10938188e-31;
}

The constant interface pattern is a poor use of interfaces. That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the class's exported API. It is of no consequence to the users of a class that the class implements a constant interface. In fact, it may even confuse them.


Worse, it represents a commitment: if in a future release the class is modified so that it no longer needs to use the constants, it still must implement the interface to ensure binary compatibility. If a nonfinal class implements a constant interface, all of its subclasses will have their namespaces polluted by the constants in the interface.There are several constant interfaces in the java platform libraries, such as java.io.ObjectStreamConstants. These interfaces should be regarded as anomalies and should not be emulated.


If you want to export constants, there are several reasonable choices. If the constants are strongly tied to an existing class or interface, you should add them to the class or interface. For example, all of the numerical wrapper classes in the Java platform libraries, such as Integer and Float, export MIN_VALUE and MAX_VALUE constants. If the constants are best viewed as members of an enumerated type, you should export them with a typesafe enum class. Otherwise, you should export the constants with a noninstantiable utility class. Here is a utility class version of the PhysicalConstants example above:

// Constant utility class
public class PhysicalConstants {
private PhysicalConstants() { } // Prevents instantiation
public static final double PLANCK_CONSTANT = 6.622e-34;
public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
public static final double ELECTRON_MASS = 9.10938188e-31;
}

So we make constructor private and fields static.


While the utility class version of PhysicalConstants does require clients to qualify constant
names with a class name, this is a small price to pay for sensible APIs. It is possible that the
language may eventually allow the importation of static fields. In the meantime, you can
minimize the need for excessive typing by storing frequently used constants in local variables
or private static fields, for example:

private static final double PI = Math.PI;
In summary, interfaces should be used only to define types. They should not be used to export constants.

Non-instantiable Utility classes - Enforce Noninstantiability With a Private Constructor

Occasionally you'll want to write a class that is just a grouping of static methods and static fields. Such classes have acquired a bad reputation because some people abuse them to avoid thinking in terms of objects, but they do have valid uses. They can be used to group related methods on primitive values or arrays, in the manner of java.lang.Math or java.util.Arrays. They can also be used to group static methods, including factory methods, for objects that implement a particular interface, in the manner of java.util.Collections. Lastly, they can be used to group methods on a final class, instead of extending the class.

Such utility classes were not designed to be instantiated: an instance would be nonsensical. In the absence of explicit constructors, however, the compiler provides a public, parameterless default constructor. To a user, this constructor is indistinguishable from any other. It is not uncommon to see unintentionally instantiable classes in published APIs.

Attempting to enforce noninstantiability by making a class abstract does not work. The class can be subclassed and the subclass instantiated. Furthermore, it misleads the user into thinking the class was designed for inheritance (Item 17). There is, however, a simple idiom to ensure noninstantiability. A default constructor is generated only if a class contains no explicit constructors, so a class can be made noninstantiable by including a private constructor:

// Noninstantiable utility class
public class UtilityClass {
// Suppress default constructor for noninstantiability
private UtilityClass() {
throw new AssertionError();
}
... // Remainder omitted
}


Because the explicit constructor is private, it is inaccessible outside of the class. The AssertionError isn't strictly required, but it provides insurance in case the constructor is accidentally invoked from within the class. It guarantees that the class will never be instantiated under any circumstances. This idiom is mildly counterintuitive, as the constructor is provided expressly so that it cannot be invoked. It is therefore wise to include a comment, as shown above.

As a side effect, this idiom also prevents the class from being subclassed. All constructors must invoke a superclass constructor, explicitly or implicitly, and a subclass would have no accessible superclass constructor to invoke.

This pattern also works well when you want the ability to cache an object. For example if you were creating a String class that is immutable. For every String "FOO" created you want one instance. If you make the class notinstantiable and instead add a String.get("foo") method, you can ensure that you return one and only one instance. For example:

public class MyString {
private MyString() { }
private WeakHashMap<String,String> map = new WeakHashMap<String,String>();
public get(String s) {
if (map.get(s))
return map.get(s);
else {
map.put(s,s);
return map.get(s);
}
}
}



In fact this pattern is used for the Java Integer class. It is recommended you use Integer.valueOf(int i). We can see why by looking at their code:

private static class IntegerCache {
private IntegerCache(){}

static final Integer cache[] = new Integer[-(-128) + 127 + 1];

static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}

/**
* Returns a <tt>Integer</tt> instance representing the specified
* <tt>int</tt> value.
* If a new <tt>Integer</tt> instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Integer(int)}, as this method is likely to yield
* significantly better space and time performance by caching
* frequently requested values.
*
* @param i an <code>int</code> value.
* @return a <tt>Integer</tt> instance representing <tt>i</tt>.
* @since 1.5
*/
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}


For any value between -128 and 127 the class has already been constructed and when you call it, you simply get a pointer to that Object.

So in conclusion when you have a class that you don't always want instantiated you should consider making the constructor private.