I practiced design patterns so that I could write code that was conscious of design. Other Design Patterns will be released frequently.
The primary goal is to understand when, what, and how to use design patterns. (I'm new to Java or a statically typed language, and I don't have a long history of python, so I think there are some things that aren't like Pythonista. If you have any suggestions, please teach me.)
This time, the creational pattern FactoryMethod.
Separate the object creation interface and the object creation role, replace the constructors of other classes with your own methods that can be overwritten by subclasses, and leave the object creation to the subclasses to improve the reusability of the class.
This sample program is based on a factory that makes identification cards (ID cards). There are four classes here.
The Product and Factory classes belong to a package called Framework. These two classes act as a framework for instantiation.
The ID and IDCardFactory classes do the actual fleshing. These belong to a package called ID Card.
Framework/factory.py
from abc import ABCMeta, abstractmethod
class Factory(metaclass=ABCMeta):
@abstractmethod
def _create_product(self, owner):
pass
@abstractmethod
def _register_product(self, product):
pass
def create(self, owner):
self.__p = self._create_product(owner)
self._register_product(self.__p)
return self.__p
The Template Method pattern is used here. The Template Method pattern is that "a superclass determines a large framework for processing, and a subclass determines the specific processing".
This class defines a large framework for processing, and subclasses are responsible for implementing both create_product and register_product methods for which specific processing has not been decided.
The create method uses both the create_product and register_product methods to create an instance of the "product".
The Factory Method pattern uses the Template Method pattern for instantiation.
Framework/product.py
from abc import ABCMeta, abstractmethod
class Product(metaclass=ABCMeta):
@abstractmethod
def use(self):
pass
Only the declaration of the abstract method use.
IDCard/idcard.py
from Framework.product import Product
class IDCard(Product):
def __init__(self, owner):
self.__owner = owner
print(self.__owner + 'Create a card for')
def use(self):
print(self.__owner + 'Use the card')
def get_owner(self):
return self.__owner
Define as a subclass of Product class, create a constructor, and define use method and get_owner method.
IDCard/idcard_factory.py
from Framework.factory import Factory
from IDCard.idcard import IDCard
class IDCardFactory(Factory):
def __init__(self):
self.__registed = []
def _create_product(self, owner):
return IDCard(owner)
def _register_product(self, product):
self.__registed.append(product.get_owner())
Implemented create_product and register_product methods.
The create_product method creates an instance of the IDCard class.
The register_product method adds the owner of the IDCard obtained by the get_owner method to the list owners.
main.py
from IDCard.idcard_factory import IDCardFactory
def main():
factory = IDCardFactory()
card1 = factory.create('Hiroshi Yuki')
card2 = factory.create('Tomura')
card3 = factory.create('Hanako Sato')
card1.use()
card2.use()
card3.use()
if __name__ == '__main__':
main()
Output result
Create a card for Hiroshi Yuki
Create a Tomura card
Create a card for Hanako Sato
I will use Hiroshi Yuki's card
I will use Tomura's card
I will use Hanako Sato's card
Since only the interface is specified and the subclass is in charge of which class to instantiate, I was able to access the method from the outside without worrying about the internal implementation.
Recommended Posts