originally posted on: henricodesjava.blog
We last left off on chapter four of Head First Design Patterns: A Brain-Friendly Guide which covers the Factory patterns. In this post we’ll cover the second pattern in the chapter, known as “Abstract Factory Pattern”.
Both of the factory patterns are responsible of encapsulating object creation, in other words, encapsulating the concrete implementation. Factory method pattern accomplished this with the use of Inheritance, the Abstract Factory Pattern accomplishes this using composition.
Lets continue to use our Pizza Store example from part 1. The textbook gives us a hypothetical example were we want to control what type of ingredients are used in all future pizza stores. It is important to note that all stores will use some type of dough, sauce, cheese, and clams. This means there will be several different types of each ingredients. This is were can group them into “family of ingredients”.
What we will do is create a factory class for each one of these regions. A Chicago, New York, and California ingredient factory. And each of these factories will implement a generic ‘PizzaIngredientFactory’ java interface. Lets take a look at the class diagram for this solution. California ingredient factory is not shown for brevity.
It’s a little messy, but take a close look at the relationships in this class diagram. What we see is that each ingredient category (Dough, Sauce, Cheese, Clams) has an interface that then has implementations appropriate to a region. And these implementations come from their respective PizzaIngredientFactory. This is a going point to give a formal definition to our pattern.
Abstract Factory Pattern: Provides an interface for creating a families of related or dependent objects without specifying their concrete classes.
Below is the PizzaIngredientFactory interface.
Below are the NYC and Chicago implementations of this interface.
We aren’t done yet. We’ll need to make changes to the Pizza so that all pizzas only use factory produced ingredients, instead of accepting any string. Below is the abstract Pizza. Take a moment to look back at my part 1 post and notice the changes made. This abstract pizza and all interfaces and implementation of the ingredients is not shown in the class diagram above for brevity.
Below is what the pepperoni pizza looks like. Notice how all the responsibility of choosing a specific type of dough, sauce, and cheese, is left up to the ingredientFactory. Which in this class is the generic interface, and can be passed a concrete implementation in the constructor. The cheese, clam, and veggie pizza look similar to this.
Finally lets take a higher level look at a client’s use of these pizzas. Below is the NYC pizza store.
And here we see the constructor for ‘NYPizzaIngredientFactory’ being set to the generic ‘PizzaIngredientFactory’ data member. Then it being passed to each pizza types constructor. BOOM, all the magic happens in the background!
That’s a lot of work and the class diagram can look a little confusing, but that’s what it takes to get an implementation of the Abstract Factory Pattern. If you want to take a look at the complete code base for this example check it out here. Thanks for reading