As a material for learning GoF design patterns, the book "Introduction to Design Patterns Learned in the Augmented and Revised Java Language" seems to be helpful. However, since the examples taken up are based on JAVA, I tried the same practice in Python to deepen my understanding.
The Factory Method pattern is one of the design patterns defined by GoF (Gang of Four). The Factory Method pattern aims to expel application-specific object creation to subclasses and improve class reusability by replacing constructors of other classes with their own methods that can be overridden by subclasses.
Also known as the Virtual Constructor pattern.
UML class diagram
(The above is quoted from Wikipedia)
The Template Method pattern for behavior is to create a general processing outline in a superclass and determine specific processing in a subclass. It seems that the Factory Method pattern is the one that applies this Template Method pattern to the scene of creating an instance.
The Factory Method pattern seems to have the following features.
--Determine how to create an instance on the superclass side --No specific class name is specified --All specific fleshing is done on the subclass side
By doing this, it seems that it will be possible to consider the framework for instance creation and the actual instance creation class separately. Actually, I would like to use the Factory Method pattern to run a sample program with the theme of "a factory that makes ID cards (ID cards)" and check the following operation.
--Create three ID cards: Hiroshi Yuki" , Tomura, Hanako Sato
--Use 3 ID cards: Hiroshi Yuki" , Tomura, Hanako Sato
$ python Main.py
I'll create Hiroshi Yuki's card
I'll create Tomura's card
I'll create Hanako Sato's card
I'll use Hiroshi Yuki's card
I'll use Tomura's card
I'll use Hanako Sato's card
If you just run the sample program, you don't really know what you want to do. Next, let's check the details of the sample program.
Similar code has been uploaded to the Git repository. https://github.com/ttsubo/study_of_design_pattern/tree/master/FactoryMethod
--Directory structure
.
├── Main.py
└── framework
├── __init__.py
├── factory.py
└── idcardfactory
├── __init__.py
└── id_card_factory.py
The Product role defines the interface that an instance should have.
In the sample program, the Product class serves this role.
framework/factory.py
from abc import ABCMeta, abstractmethod
... (snip)
class Product(metaclass=ABCMeta):
@abstractmethod
def use(self):
pass
In the role of Creator, it is responsible for generating Product. I don't know anything about the Concrete Product role that is actually generated.
In addition, the Creator role provides methods for creating each part of the instance.
In the sample program, the Factory class serves this role.
framework/factory.py
from abc import ABCMeta, abstractmethod
class Factory(metaclass=ABCMeta):
def create(self, owner):
p = self.createProduct(owner)
self.registerProduct(p)
return p
@abstractmethod
def createProduct(self, owner):
pass
@abstractmethod
def registerProduct(self, product):
pass
... (snip)
The ConcreteProduct role is a class that implements the interface for the Product role. The method that will be called after the actual instance creation is defined here.
In the sample program, the ʻIDCardProduct` class serves this role.
framework/id_card_factory.py
from framework.factory import Factory, Product
... (snip)
class IDCardProduct(Product):
def __init__(self, owner):
self.owner = owner
print("I'll create {0}'s card".format(self.owner))
def use(self):
print("I'll use {0}'s card".format(self.owner))
The ConcreteCreator role is a class that implements the interface for the Creator role. Determine the class to make a specific product.
In the sample program, the ʻIDCardFactory` class serves this role.
framework/id_card_factory.py
from framework.factory import Factory, Product
class IDCardFactory(Factory):
def __init__(self):
self.owners = []
def createProduct(self, owner):
return IDCardProduct(owner)
def registerProduct(self, product):
self.owners.append(product.owner)
... (snip)
In the sample program, the startMain method serves this role.
Main.py
from framework.idcardfactory.id_card_factory import IDCardFactory
def startMain(factoryObject):
card1 = factoryObject.create("Hiroshi Yuki")
card2 = factoryObject.create("Tomura")
card3 = factoryObject.create("Hanako Sato")
card1.use()
card2.use()
card3.use()
if __name__ == "__main__":
startMain(IDCardFactory())
-[Finishing "Introduction to Design Patterns Learned in Java Language" (Not)](https://medium.com/since-i-want-to-start-blog-that-looks-like-men-do/java Introduction to Design Patterns Learned in Languages-Finishing-No-2cc9b34a30b2) -Factory Method pattern from "diary of tachikawa844"
Recommended Posts