Ответ
Фабричный метод (Factory Method) — это порождающий паттерн проектирования, который определяет общий интерфейс для создания объектов в суперклассе, но позволяет подклассам изменять тип создаваемых объектов.
Он делегирует логику инстанцирования дочерним классам, что позволяет добавлять новые типы продуктов, не изменяя основной код.
Основные компоненты:
- Продукт (Product): Абстрактный класс или интерфейс для объектов, которые создает фабричный метод.
- Конкретный продукт (Concrete Product): Реализация интерфейса продукта.
- Создатель (Creator): Абстрактный класс, который объявляет фабричный метод, возвращающий объект продукта.
- Конкретный создатель (Concrete Creator): Класс, который переопределяет фабричный метод для создания конкретного продукта.
Пример реализации на Python
Представим систему для отправки уведомлений по разным каналам (Email, SMS).
from abc import ABC, abstractmethod
# 1. Интерфейс Продукта
class Notification(ABC):
@abstractmethod
def send(self, message: str):
pass
# 2. Конкретные Продукты
class EmailNotification(Notification):
def send(self, message: str):
print(f"Отправка Email: {message}")
class SmsNotification(Notification):
def send(self, message: str):
print(f"Отправка SMS: {message}")
# 3. Абстрактный Создатель
class NotificationCreator(ABC):
@abstractmethod
def create_notification(self) -> Notification:
"""Это и есть Фабричный метод"""
pass
def send_notification(self, message: str):
notification = self.create_notification()
notification.send(message)
# 4. Конкретные Создатели
class EmailCreator(NotificationCreator):
def create_notification(self) -> Notification:
return EmailNotification()
class SmsCreator(NotificationCreator):
def create_notification(self) -> Notification:
return SmsNotification()
# --- Использование ---
def client_code(creator: NotificationCreator, message: str):
creator.send_notification(message)
# В зависимости от выбранной "фабрики", будет создан и использован нужный продукт
client_code(EmailCreator(), "Hello via Email!")
# Вывод: Отправка Email: Hello via Email!
client_code(SmsCreator(), "Hello via SMS!")
# Вывод: Отправка SMS: Hello via SMS!
Преимущества:
- Гибкость: Легко добавлять новые типы продуктов и их создателей.
- Слабая связанность: Код клиента работает с абстрактным создателем и продуктом, не зная их конкретных реализаций.
- Соблюдение принципа открытости/закрытости (OCP): Можно вводить новые типы продуктов, не изменяя существующий клиентский код.