Hi everyone. In Chapter four ofHead First Design Patterns: A Brain-Friendly Guidewe learn about the Factory pattern. The text begins by talking about a programming idiom known as the ‘the Simple Factory’ as a warm up to two real Factory patterns. The first is known as “Factory Method” and the second “Abstract Factory”.
Lets begins by introducing the problem that the factory pattern is solving. When we write code that uses the java keyword new, we are calling constructors to concrete classes and essentially creating a hard dependency on a concrete class. The snippet below shows how a concrete dependency for three different duck classes is created, this can quickly get out of hand. (chapter 1 talked about ducks a lot).
The Factory Patterns can help us clean this up and decouple these dependencies. A new design principle is introduced to help define this design mistake above.
Dependency Inversion Principle: Depend upon abstractions. Do not depend on concrete classes.
Lets give an example to help illustrate the design pattern. I’m going to use the same pizza shop example in the text. Lets say we have our own pizza shop, and we got some code for making pizzas that looks like this.
As soon as we start adding new pizza types, this class can easily get out of hand with if-statements.As we learned in earlier chapters we need to identify what part of the this code is likely to change, and what is likely not to change, and separate them.
What the Factory patterns suggest we do is move all the constructors that are likely to change and put them in class of their own. Furthermore, what if our pizza store needs to be able to create groups of different types of pizzas, say if we had to make different kind of pizzas for the New York and another different type for Chicago (see below).
The factory patterns we’ll introduce allow us to organize and decouple the client from the concrete classes. All factory patterns encapsulates object creation, but lets give a formal definition for the first of our factory patterns.
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.
Lets take a look at a class diagram with the factory method pattern design for our pizza store problem.
First a class diagram for the group known as the “creator” classes. These are the classes that are responsible for pizza creation. The abstract creator contains the common code between all pizza creations, that is prepare() bake() cut() box() methods. It also contains the two abstract methods createPizza() and orderPizza(). The concrete creators is where we use the Java keyword new and instantiate classes (known as product classes).
Next we have the Product Classes. These are the classes that we instantiate in the concrete creators. The abstract product serves as a generic type so that the creators don’t need to know what kind of pizza they are making, they just need to know that it is of pizza type.
Now lets take a look at some code for this Factory Method Pattern implementation for our New York and Chicago pizza stores.
New York City concrete creator:
Chicago concrete creator:
Next, our group of product classes. First the abstract product. Note that the common code between all pizzas is kept here. Obviously we don’t have real implementation for these, so we simply print to standard output.
I won’t show all the concrete products, but here are a two, for a New York Pizza store, and a Chicago pizza store.
Each concrete product class gets to decide the name, the type of dough, sauce and toppings it has. Here all we see are strings being set, but you get the idea. Then what happens with these ingredients is out of the concrete product’s control (it’s in the abstract product).
Finally lets take a look at a client class making use of this awesome factory pattern. The nyStore and the chicagoStore are our two “factories” for New York style and Chicago style pizzas. If you run this code below, you’ll see print statements that describe the preparation with each pizza’s specific ingredients and then each pizzas common baking, cutting, and boxing steps.
If you are interested in looking and running this example, take a look at this repo here. Thats it! This Factory Method pattern relies on inheritance to delegate object creation. My next post will be part two on the topic of Factory patterns where I”ll talk about the Abstract Factory pattern, which relies on composition instead of inheritance. Thanks for reading