Design Patterns with Python Part 2: The Factory
Enter the Factory
A factory creates objects. Yes I know, mindblowing stuff. Furthermore, we can comfortably say that a factory creates different type of objects but in the greater scheme of life those objects are similar in nature. Succinctly, a factory create objects of another type. Meaning, factory cannot create a factory.
Simple Factory Pattern
The simplest form of the Factory DP, is to have a methodology to create different types of objects. As we see below, no direct object instantiation happens.
ABCMeta is a Python metaclass which can be used to design a class as abstract. Our abstract class, Dog that is, has the race_name() method. Once the metaclass defined, we can reuse this through inheritance. The abstractmethod decorator is needed because a class that has a metaclass derived from ABCMeta cannot be instantiated unless all abstract methods/properties are overriden.
Factory Method Pattern
The Factory Method pattern expands on the previous one and will basically take care of following enhancements:
- An interface is created for object creation. From this, the subclass is responsible for object creation and not the factory This will result in a much more flexible and customizable design. Furthermore, the loos coupling results in an easy high level interface, easily maintainable where the user/client doesn’t have to bother with arguments and instantiations.
Firstly, we define the so-called “Product Interface”. This is done by defining the different parts from which a cyborg can be created. Afterwards, we define the “Creator”. In our case, this is the class Borg which provides a factory method createBorg(). The Creator class doesn’t know about the needed parts for creating a Borg. That’s where the defaultBorg- and airBorg class comes in play, aka the “ConcreteCreator classes”. Both classes, implement the createBorg() abstract method and their respective parts methods at runtime.
Abstract Factory pattern
This takes the factory pattern and further by applying a mechanic in which an interface is created in which different related objects can be created without specifying the concrete classes.
Firstly, the abstract base class PizzaFactory is defined with its two abstract methods. The 2 concrete factories are IndianPizzaFactory and USPizzaFactory. No surprises here.
Secondly, we define the abstractions for our products, which are VegPizza and NonVegPizza with each their methods. So identical products from different factories can be differently made.
Those different concrete products: DeluxVeggiePizza, ChickenPizza, HamPizza, MexicanVegPizza are then each defined with appropriate methods.
Et voila! Now go fetch dat pizza and pat yeself hooman.