Что это такое
Паттерн Фабричный метод (Factory Method) прячет создание объекта за функцией. Вызывающий код говорит, что ему нужно, — а фабрика решает, какой конкретный класс создать, и возвращает его.
Вызывающий код никогда не обращается к конкретным классам напрямую, поэтому новые виды можно добавлять, не меняя вызывающий код. В Python это просто функция new_something(), которая возвращает протокол.
Пример: фабрика хранилищ
new_storage("disk") и new_storage("memory") возвращают разные конкретные классы за одним и тем же протоколом Storage — вызывающий код не видит разницы, и ему это не нужно.
Фабрика выбирает класс
Конструкция match по видам находится в одном месте — в фабрике. Остальная программа знает только протокол.
Вывод: полная программа на Python
from typing import Protocol
class Storage(Protocol):
def save(self, data: str) -> str: ...
class DiskStore:
def save(self, data: str) -> str:
return "диск: сохранено " + data
class MemoryStore:
def save(self, data: str) -> str:
return "память: хранится " + data
# Фабрика решает, какой конкретный класс создать.
def new_storage(kind: str) -> Storage:
match kind:
case "memory":
return MemoryStore()
case _:
return DiskStore()
for kind in ["disk", "memory"]:
s = new_storage(kind)
print(s.save("order #1042"))
Когда его использовать
Используйте его, когда конкретный класс зависит от того, что известно только во время выполнения, — значения из конфигурации, выбора пользователя, окружения, — или когда вы хотите, чтобы логика создания была ровно в одном месте.
Не используйте его, когда есть только одна реализация и вторая не предвидится. Для store = DiskStore() фабрика не нужна.
Плюсы и минусы
Плюсы: логика создания находится в одном месте; вызывающий код зависит только от протокола; добавление нового вида затрагивает только фабрику.
Минусы: ещё один уровень, через который нужно читать код; при единственной реализации это пустая формальность.