Factory Pattern in Java

Intro

Often, designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Prototype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed. — Design Patterns Explained Simply

In class-based programming, the factory pattern is a creational pattern that uses factory to deal with the problem of creating objects without having to specify the exact class of the object that will be created[wiki]. A factory pattern example can be found as below:

public interface Shape {
void draw();
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
public class ShapeFactory {

public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
}
return null;
}
}

Here is a sample code to use factory pattern:

public class FactoryPatternDemo {

public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();

Shape shape = shapeFactory.getShape("CIRCLE");
shape.draw();
}
}

OCP

So far, everything looks so straightforward and you might be able to implement it in some of your projects. But, did you notice that ShapeFactory violates Open/Closed Principle? [link]

In object-oriented programming, the open/closed principle states “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”; that is, such an entity can allow its behaviour to be extended without modifying its source code.

It does, if you need add one more Shape, you have to add some code in getShape() method. However, factory pattern is to save you from knowing subclasses object creation. The violation is the price for that.

Even though, we can still have two solutions: Use Reflection, Subclass Factory.

Category

For factory pattern, there are three main categories: factory, factory method, abstract factory.[link]

Factory is “fixed”, in that you have just one implementation with no subclassing.

Factory method is generally used when you have some generic processing in a class, but want to vary which kind of fruit you actually use.

Abstract factory is normally used when you want to be able to create a whole family of objects that need to be of “the same kind”, and have some common base classes.

// Factory
class FruitFactory {
public Apple makeApple() {
}

public Orange makeOrange() {
}
}
// Factory Method
abstract class FruitPicker {
protected abstract Fruit makeFruit();

public void pickFruit() {
private final Fruit f = makeFruit();
}
}
class OrangePicker extends FruitPicker {
@Override
protected Fruit makeFruit() {
return new Orange();
}
}

Factory Method Example [link]

// Factory Interface
public interface Blacksmith {
Weapon manufactureWeapon(WeaponType weaponType);
}
public class ElfBlacksmith implements Blacksmith {
public Weapon manufactureWeapon(WeaponType weaponType) {
return new ElfWeapon(weaponType);
}
}
public class OrcBlacksmith implements Blacksmith {   
public Weapon manufactureWeapon(WeaponType weaponType) {
return new OrcWeapon(weaponType);
}
}
public interface Weapon {
WeaponType getWeaponType();
}
public class ElfWeapon implements Weapon {
private WeaponType weaponType;
  public ElfWeapon(WeaponType weaponType) {
this.weaponType = weaponType;
}
}
public class OrcWeapon implements Weapon {
private WeaponType weaponType;
  public OrcWeapon(WeaponType weaponType) {
this.weaponType = weaponType;
}
}
public enum WeaponType {
SHORT_SWORD("short sword"), SPEAR("spear"), AXE("axe"), UNDEFINED("");
private String title;

WeaponType(String title) {
this.title = title;
}
  @Override  public String toString() {
return title;
}
}
public static void main(String[] args) {
// Create Factory
Blacksmith blacksmith = new OrcBlacksmith();
// Factory create object
Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
}

Application

Here, we are going to illustrate some source code using factory pattern.

// java.util.Calendar
private static
Calendar createCalendar(TimeZone zone,
Locale aLocale)
{
Calendar cal = null;

String caltype = aLocale.getUnicodeLocaleType("ca");
if (caltype == null) {
// Calendar type is not specified.
// If the specified locale is a Thai locale,
// returns a BuddhistCalendar instance.
if ("th".equals(aLocale.getLanguage())
&& ("TH".equals(aLocale.getCountry()))) {
cal = new BuddhistCalendar(zone, aLocale);
} else {
cal = new GregorianCalendar(zone, aLocale);
}
} else if (caltype.equals("japanese")) {
cal = new JapaneseImperialCalendar(zone, aLocale);
} else if (caltype.equals("buddhist")) {
cal = new BuddhistCalendar(zone, aLocale);
} else {
// Unsupported calendar type.
// Use Gregorian calendar as a fallback.
cal = new GregorianCalendar(zone, aLocale);
}

return cal;
}