When to use Factories

Question: 

I was wondering how you decide when to use the abstract factory pattern and when not to. Obviously, the factory pattern is useful in that it prevents code from having to know the implementation of a procedure, but using the factory pattern for every single class is absurd.

In hangman, for example, the abstract factory pattern was used to created the word list and the body, but not for the hangman game and, the running and not-running states (they were instantiated directly with "new RunningState" or "new NotRunningState").

In the list structures, a factory was used to create an IEmptyList and an INEList, but not an LRStruct or an ANode used by the LRstruct.

Why is it that you made the choices you did and what general rule of thumb do you recommend?

Answer:

It boils down to whether or not it makes sense in the context of the problem at hand to decouple the process of manufacturing an object and its usage.

In hangman, HangmanGame is a concrete class designed specifically to play the game of hangman using specifically the body parts represented by IBody and the words represented by IWord.  Should we want to model an abstract notion of a hangman game and capture all possible implementations of such a game, then  we will need an abstract game interface and have a specific hangman  factory for each implementation of the hangman game.  For our project, we decide to have just one concrete HangmanGame class and thus need no factory.

In contrast, IBody and IWord have factories because we want the flexibility of different implementations.  To be consistent with what we have been doing with IList, we should have abstract factory interfaces for IBody and IWord also.  The hangman game should not care how the body parts and the words are created and thus should be decoupled from the construction of these objects.

We could use a factory to create appropriate states for HangmanGame, but we chose not to do so since, in the context of what we are trying to do, there is no need to allow for different implementations of the states for HangmanGame.

The same can be said for LRStruct.  However, as in turns out, should we want to add "lazy evaluation" to LRStruct, we will need to have a abstract factory that manufactures concrete LRStructs with a specific abstract "lazy evaluation" strategy (as in strategy pattern)!  In this case the constructors for LRStruct are no longer public.

Now, remember the Pizza problem at the beginning of the semester?  Let's take a look at the following GUI application:

http://www.owlnet.rice.edu/~comp201/04-spring/labs/lab09/

Can we dynamically load any shape without using factories?