Monday, March 18, 2013

Factory Method Pattern

The Factory Method Pattern encapsulates object creation by letting subclasses decide what objects to create. The creator class defines an abstract factory method that the subclasses implement to produce products. Factory method is known as a creational pattern - it's used to construct objects such that they can be decoupled from the implementing system.

The GoF book on Design Patterns defines it as -
Define an interface for creating an object, but let the subclasses decide which class to instantitate. The Factory method lets a class defer instantiation to subclasses.
In this definition the term "interface" is used in the general sense, meaning - a concrete class implementing a method from a supertype (a class or interface).

The Factory method builds on the concept of a Simple Factory, but lets the sub-classes decide which implementation of the concrete class to use. Simple factory is a programming idiom rather than a pattern, where object creation is relegated to a method. Factory Method pattern builds on it - deferring object creation to sub-classes.

A simple factory can also be defined as a static method and is often called a static factory. This way we don’t have to instantiate an object to make use of the create method. But the disadvantage is that, we can’t subclass and change the behavior of the create method.

Example code from http://java.dzone.com/articles/design-patterns-factory. First an interface and an implementation for the product:

public interface Logger {
	public void log(String message);
}
public class XmlLogger implements Logger {

	@Override
	public void log(String message) {
		System.err.println(message);
	}

}
Creator with the abstract factory method:
public abstract class AbstractLoggerCreator {
	
	//factory method
	public abstract Logger createLogger();
	
	public Logger getLogger() {
		Logger logger = new XmlLogger();
		return logger;
	}
}
Now the concrete creator class:
public class XmlLoggerCreator extends AbstractLoggerCreator {
	@Override
	public Logger createLogger() {
		XmlLogger logger = new XmlLogger();
		return logger;
	}
}
Finally the client code to test the pattern:
public class FactoryMethodClient {
	private void methodA(AbstractLoggerCreator creator) {
		Logger logger = creator.createLogger();
		logger.log("message");
	}

	public static void main(String[] args) {
		AbstractLoggerCreator creator = new XmlLoggerCreator();
		FactoryMethodClient client = new FactoryMethodClient();
		client.methodA(creator);
	}

}
Downside of the pattern is that it might be over-complicated. In a lot of cases, a simple factory pattern will work fine. The FactoryMethod just allows further decoupling, leaving it to the sub-classes of the Creator to decide which type of concrete Product to create.

No comments: