Rusty Divine

Live, Love, Learn, Teach

Learning Design Patterns - Factory Pattern

This week I'll be manufacturing the Factory Pattern in my series on design patterns plucked from this book and from examples on the Internet.

What is it?
The factory pattern comes in a few flavors; the simple factory, the factory method, and the abstract factory patterns. Regardless of the implementation, the goal of the factory pattern is to encapsulate object creation so that the design isn't as dependant on concrete classes. By relying less on instantiating concrete classes, common code can remain untouched when those classes undergo changes.

The simple factory isn't actually a pattern; it's more of a design principle. The simple factory encapsulates the object creation code, but keeps control over how the object is created. Simple factories are often designed as a class with a static method (aka static factory) that returns the object requested.

The factory method pattern takes the simple factory one step further by becoming an abstract class that has an abstract method for instantiating the object (at least usually; they don't have to be abstract if there is only one object type). Subclasses then inherit from the factory and are responsible for actually creating the object, in what is commonly referred to as deciding how to instantiate the object (it really just means the factory doesn't know or care what object is being returned). The factory often uses the returned object to perform other tasks.

The abstract factory pattern enforces the Dependency Inversion Principle (Impress your peers with that one)! Simply stated, that means the design should depend on abstractions over concrete classes; no variable should hold a reference to a concrete class, no class should derive from a concrete class, and no method should override an implemented method of its base classes. This, of course, is impossible to enforce completely in an application of any significant complexity, but it is a guiding principal. The abstract factory pattern groups like objects together by providing an interface to them without specifying their concrete classes.

Where is it used?
Anywhere new objects are being instantiated with the 'new' keyword, or however it is done in the language being used.

But why?
The factory patterns reduce common code's dependency on instantiating objects with the 'new' keyword. By programming to abstractions instead, the code achieves loose coupling – i.e., it is less dependant on the design of the concrete classes.

OK, and how is it implemented?

In Ruby:

In .Net:

In Java:

// Simple factory
public class SimpleWidgetFactory {
	public Widget createWidget(String type) {
		Widget w = null;
		//handle the creation details here
		if (type.equals("rubber")) {
			w = new RubberWidget();
		}
		return w;
	}
}

// Factory Method
public abstract class WidgetFactory {
	public Widget orderWidget(String type) {
		Widget w;
		w = createWidget(type);
		return w;
	}
	//let the subclass that implements this decide how
	//to create the widget
	protected abstract Widget createWidget(String type);
}

// Abstract Factory pattern
//First, create the interface for the factory
public interface WidgetIngredientFactory {
	public Tar createTar();
	public Spring createSpring();
}
//implement the factory in one or more different ways
public class DurableWidgetIngredientFactory  implements WidgetIngredientFactory {
	public Tar createTar() {
		return new ThickTar();
	}
	public Spring createSpring(); {
		return new TiggerSpring();
	}
}
public class WeakWidgetIngredientFactory implements WidgetIngredientFactory {
	public Tar createTar() {
		return new LiquidTar();
	}
	public Spring createSpring() {
		return new RustedSpring();
	}
}

//The factory depends on this abstract class, and the 
//sub classes depend on this abstract class
public abstract class Widget {
	Tar tar;
	Spring spring;
	abstract void prepare();
void Dodad() {
	System.out.println("Widget dodad");
}
}

//Now, look at the actual widget subclass
public class MyWidget extends Widget {
	WidgetIngredientFactory wf;
	public MyWidget(WidgetIngredientFactory wf) {
		//pass in the factory type, like DurableWidgetIngredientFactory
		this.wf = wf;
	}
	void prepare() {
		//the factory now takes care of creation!
		tar = wf.createTar();
		spring = wf.createSpring();
	}
}
blog comments powered by Disqus