Что такое паттерн ‘Фабричный метод’ и как его реализовать на Python

Ответ

Фабричный метод (Factory Method) — это порождающий паттерн проектирования, который определяет общий интерфейс для создания объектов в суперклассе, но позволяет подклассам изменять тип создаваемых объектов.

Он делегирует логику инстанцирования дочерним классам, что позволяет добавлять новые типы продуктов, не изменяя основной код.

Основные компоненты:

  1. Продукт (Product): Абстрактный класс или интерфейс для объектов, которые создает фабричный метод.
  2. Конкретный продукт (Concrete Product): Реализация интерфейса продукта.
  3. Создатель (Creator): Абстрактный класс, который объявляет фабричный метод, возвращающий объект продукта.
  4. Конкретный создатель (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): Можно вводить новые типы продуктов, не изменяя существующий клиентский код.