JavaScript Design Patterns: Factory
Table of Contents
Factories encapsulate and separate object creation from the rest of your code. In situations where the creation of an object can be complex or subject to change a factory can act as a nice buffer to help keep things tidy. Without proper planning Factories can lead to class explosions; as a result the pattern can be both a blessing and a curse depending on how it’s used.
Formal Definition
Factory Method
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
Abstract Factory
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
Also Known As
- Virtual Constructor (Factory Method)
- Kit (Abstract Factory)
Simple Factory vs Factory Method vs Abstract Factory
The phrase “Factory Pattern” is rather overloaded so I’m going to give you a quick crash course in the three main types of factories.
A simple factory is an object which encapsulates the creation of another object, shielding that code from the rest of your application.
It’s common to parameterize simple factory methods to increase the number of products they’re able to return.
The actual implementaiton of createUser
might look something like this:
Typically the return value from a factory is known as the Product
. In the case of our UserFactory
there are two Products: Admin
and Customer
. It’s important for these products to maintain a consistent interface so the client can use any product from our factory without needing to do elaborate checks to see if a particular method exists.
Factory Method
While the Simple Factory is a nice start and good for many situations it’s possible to extend this even further through the use of the Factory Method pattern.
The Factory Method Pattern defines an interface
for creating an object, but lets subclasses decide which
class to instantiate. Factory Method lets a class defer
instantiation to subclasses.
Factory Method defines one method, createThing
for instance, which is overriden by subclasses who decide what to return. The Factories and Products must conform to interfaces for clients to be able to use them.
In Head First Design Patterns a Factory Method pattern is used to allow a PizzaStore to define many subclasses such as ChicagoPizzaStore, CaliforniaPizzaStore, NewYorkPizzaStore. Each subclass overrides createPizza
and returns its own particular style of pizza (ie: a ChicagoPizza or a CaliforniaPizza). The main take away is that there is only one method, createPizza
, that does anything. By subclassing and overriding this method we can offer aditional flexibility beyond what’s possible with the Simple Factory.
Abstract Factory
Unlike the Factory Method pattern, Abstract Factory defines any number of methods which return Products.
The Abstract Factory Pattern provides an interface
for creating families of related or dependent objects
without specifying their concrete classes.
Again in Head First Design Patterns, an Abstract Factory pattern is used to provide different Pizza ingredients depending on the type of Pizza. For instance, a ChicagoPizza would be given a ChicagoPizzaIngredients factory with methods like createDough
, createSauce
, createCheese
, etc. A CaliforniaPizzaIngredients factory would also implement createDough
, createSauce
and createCheese
. In this way the factories would be interchangeable.
The authors are keen to point out that the methods of the Abstract Factory (createDough
, createSauce
, etc) look very similar to the Factory Method (createPizza
). One way of thinking about things is that an Abstract Factory can be composed of Factory Methods.
The Factory Method in JavaScript
Since I’ve already shown a basic Simple Factory let’s take a stab at doing the Factory Method in JS. We’ll continue with the PizzaStore theme since I’ve already spelled out how each pattern applies to it. We’re going to do this without the use of the new
keyword and instead we’ll take advantage of JavaScript’s prototypes. How you ask?
The very awesome Object.create
ECMAScript 5 introduced a new method of the Object
prototype called create
. You can read up on it in full detail on MDN. In a nutshell it lets you pass in a prototype and receive a new object which points to that prototype. Object.create
is actually a simple Factory Method! Here’s an example:
One very cool feature of Object.create
is that it accepts a properties object which is then mixed in to the returned object. The code can get a little verbose since it uses defineProperty syntax so instead let’s steal a function from Yehuda Katz which lets us do something very similar.
Now that we have that we can continue on our way. One quick caveat though! Some browsers *cough* IE *cough* don’t support Object.create
so we need to shim it. Thankfully MDN has got our back:
Drop that into your page and you should be able to use Object.create like we are above. Note that the shim does not support the second properties object. For our purposes that’s ok but definitely keep it in mind if you’re thinking of using it.
Back to the Factory Method
With Object.create
and fromPrototype
in hand we’re ready to tackle our first Factory Method.
Let’s start by creating a PizzaStore:
Easy enough. Ok now let’s extend the PizzaStore so we have two variations: ChicagoPizzaStore and CaliforniaPizzaStore.
The Abstract Factory in JavaScript
Since we have a variety of pizza styles we might also have a variety of ingredients. Let’s see if we can accomodate all the different kinds.
In the above example Ingredients
is our Abstract Factory. We know that for every
different kind of pizza we’ll need different ingredients and therefore a new Factory Method. We also know that we have different styles of pizza so we’ll need Chicago style ingredients and California style ingredients. When a client wishes to grab some ingredients for a particular kind of pizza they just say:
The object that is returned by the call createCaliforniaStyle
is the concrete implementation of our Abstract Ingredients object. In other words, if Ingredients
is the Abstract Factory, then the object returned by createCaliforniaStyle
could also be thought of as a CaliforniaIngredients
object. It is a subclass of Ingredients
if you want to think of it that way. The returned object extends Ingredients
and overrides its Factory Methods with its own methods. In so doing we provide a lot of additional flexibility to our app. If we want to add a Hawaiian style ingredients we just add a createHawaiianStyle
method.
If you recall from the previous article on Decorators we talked about the Open-Closed Principle which states that “classes should be open for extension but closed for modification.” You’ll notice that adding a createHawaiianStyle
method would actually violate this principle so it should be noted that when using an Abstract Factory approach you’ll probably have to reopen the class/object a few times to modify it. Not ideal but depending on your use case this might not be such big deal and you might prefer the flexibility and organization that the factory offers.
Grab the Example Source
Related Patterns
- Template Methods: Factory Methods are usually called within Template Methods.
- Singleton: A concrete factory is often a singleton.
Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John (1994-10-31). Design Patterns: Elements of Reusable Object-Oriented Software. Pearson Education (USA).
Table of Contents
Thanks for reading! If you have questions or feedback please leave a comment below. - Rob
You should follow me on Twitter here.