Ever heard of Factory Methods?
Posted by Michel Barakat on Wednesday, February 4, 2009
Under: Java
Whenever we want an object to initialize itself, we normally go for public constructor definition. But have you ever think about static factory method? A class can provide similar or some addition fetchers as in constructor to its clients with static factory method.
Factory methods are simply methods that instantiate objects. Some factory methods in the Java 2 API that you would likely have used are the getInstance() and valueOf() methods. getInstance() is the conventional instantiation method in singletons, while valueOf() are often type-conversion methods, like in String.valueOf(int i).
Constructor allows object to initialize themselves when they are created. Once defined, the constructor is automatically called immediately as the object is created, before the new operator completes.
A simple example of constructor:
ConstructorExample.java
class ConstructorDemo
{
public int a=42;
ConstructorDemo()
{
System.out.println(”a = ” + a);
}
}
class ConstructorExample
{
public static void main(String [] args)
{
ConstructorDemo ConObj = new ConstructorDemo();
}
}
Output:
a = 42
There is a less popular technique that should also be a part of every programmer’s toolkit for the similar propose of constructor. A class can provide a public static factory method, which is simply a static method that returns an instance of the class. When a method is static, it can be accessed before any objects of its class are created, and without reference to any object.
Static factory methods have names
Static factory methods have names
A class can have only a single constructor with a given signature, which is a restriction in cases where a class needs to be able to be instantiated using identical parameter lists. In cases like this, you can replace constructors with static factory methods with more intuitive names that highlight their differences.
Static factory methods can improve performance
This is because static factory methods do not have to actually instantiate new objects each time they are invoked. This is what allows for the Singleton pattern, where a single instance is returned. It also allows instances to be cached within the object in cases where object instantiation is expensive (like for the case of instantiation of fields from a database) or frequently done.
Static factory methods can return a subtype of their return type
This allows for interfaces to be returned by static factory methods, which is best exemplified in the Collections Framework. Needless to say, forcing a client to refer to the returned object by its interface rather than its actual class is a good practice.
Also, the class of the object returned can be private (non-public), so there is a degree of encapsulation where the private class can be modified without impacting clients of the API (possibly for bug-fixing or improvements, or just plain maintainence). The private classes can also vary depending on the parameters to the static factory, so long as they are subtypes of the return type, allowing for greater flexibility.
Classes without public or protected constructors cannot be subclassed
This is an unavoidable fact, so classes designed for inheritance must have at least 1 public constructor to be able to be subclassed.
A simple example of a static factory method:
StaticExample.java
class StaticDemo
{
static int a=42;
static void callme()
{
System.out.println(”a = ” + a);
}
}
class StaticExample
{
public static void main(String [] args)
{
StaticDemo.callme();
}
}
Output:
a = 42
Providing a static factory method instead of a public constructor has both advantages and disadvantages.
The advantages of static factory method are:
- Unlike constructor, it has names which make class easier to use.
- Unlike constructor, they are not required to create a new object each time they are invoked.
- Unlike constructor, they can return an object of any subtype of their return type.
The disadvantages of static factory methods are:
- Classes without public or protected methods cannot be subclassed.
- They are not readily distinguishable from other static method.
In conclusion, you can use static factory methods for a more intuitive API, to improve performance via object-caching, to implement singletons, in interface-based frameworks, and to return objects of private classes; and use constructors in classes designed for inheritance (there shouldn’t be many of these) and for greater visibility in API documentation (since they appear in a separate table in standard Javadocs).
In : Java