The Abstract Factory Pattern provides a way to encapsulate a group of individual factories that have a common theme. It embodies the intent of a normal factory, i.e. remove the need for code using an interface to know the concrete implementation behind the interface, but applies to a set of interfaces and selects an entire family of concrete classes which implement those interfaces.
As an example, I might have interfaces Button, TextField and Scrollbar. I might have WindowsButton, MacButton, FlashButton as concrete classes for Button. I might have WindowsScrollBar, MacScrollBar and FlashScrollBar as concrete implementations for ScrollBar. Using the Abstract Factory Pattern should allow me to select which windowing system (i.e. Windows, Mac, Flash) I want to use once and from then on should be able to write code that references the interfaces but is always using the appropriate concrete classes (all from the one windowing system) under the covers.
Suppose we want to write a game system. We might note that many games have very similar features and control.
We decide to try to split the common and game-specific code into separate classes.
First let's look at the game-specific code for a Two-up game:
Now, let's look at the game-specific code for a number guessing game:
Now, let's write our factory code:
The important aspect of this factory is that it allows selection of an entire family of concrete classes.
Here is how we would use the factory:
Note that the first line configures which family of concrete game classes we will use. It's not important that we selected which family to use by using the factory property as shown in the first line. Other ways would be equally valid examples of this pattern. For example, we may have asked the user which game they wanted to play or determined which game from an environment setting.
With the code as shown, the game might look like this when run:
If we change the first line of the script to
GameFactory.factory = guessFactory, then the sample run might look like this: