Фабрика — это просто способ создания объектов. В отличие от шаблона Builder, который создает объект по частям, factory создает его оптом.
Есть три способа сделать это -
- Заводской метод
- Фабрика
- Абстрактная фабрика
Заводской метод
class TypePoint(Enum): CARTESIAN, POLAR class Point: def __init__(self, x, y, type_point): if type_point == TypePoint.CARTESIAN: self.x = x self.y = y elif type_point == TypePoint.POLAR: self.x = x * cos(y) self.y = x * sin(y)
Если вводится какой-то новый тип точки, нам нужно изменить метод __init__. Это нарушает принцип открытия-закрытия.
Идея состоит в том, чтобы в этом случае создавать статические методы всякий раз, когда вводится новый тип точки. Фабричный метод — это не что иное, как статический метод.
class Point: def __init__(self, x, y): self.x = x self.y = y @staticmethod def type_point_cartesian(x, y): return Point(x, y) @staticmethod def type_point_polar(x, y): return Point(x * cos(y), x * sin(y)) # How to access p1 = type_point_cartesian(1,2) p2 = Point(2,3) #No way to avoid this since no concept of private initializers. p3 = type_point_polar(4,5)
Фабрика
Давайте применим принцип единой ответственности к приведенному выше примеру, и он станет фабрикой. Фабрику можно рассматривать как класс с фабричными методами. Эти фабричные методы не обязательно должны быть статическими, так как теперь они находятся в другом классе. Фабрика также может быть внутренним классом, что имеет место в других языках программирования, но поскольку __init__ является общедоступным в python, на самом деле не имеет значения, является ли фабрика внутренней по отношению к классу Point или вне его.
Давайте посмотрим на пример, где factory является внутренним классом.
class Point: def __init__(self, x = 0, y = 0): self.x = x self.y = y class PointFactory: def type_point_cartesian(self, x, y): return Point(x, y) def type_point_polar(self, x, y): return Point(x * cos(y), x * sin(y)) factory = PointFactory() # This partially makes factory Singleton # How to access p1 = Point() p1.factory.type_point_polar(2, 3)
Абстрактная фабрика
Здесь особо нечего объяснять. Просто подключите абстрактный класс, и он станет абстрактной фабрикой.
class HotDrinkFactory: #Abstract Factory def prepare(): pass class TeaFactory(HotDrinkFactory): def prepare(): return Tea() class CoffeeFactory(HotDrinkFactory): def prepare(): return Coffee() def make_drink(type): if type == 'Tea': return TeaFactory.prepare() elif type == 'Coffee': return CoffeeFactory.prepare() else: return None #Just call the make_drink method with the required type
Ссылка –
Курс Udemy: https://www.udemy.com/course/design-patterns-python/