Что такое паттерн ‘Фабрика’ и когда его следует применять

Ответ

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

Основные цели и преимущества:

  • Инкапсуляция логики создания: Клиентскому коду не нужно знать о конкретных классах и сложностях их создания. Он просто запрашивает нужный объект у фабрики.
  • Снижение связанности (Decoupling): Клиентский код зависит от абстрактного интерфейса продукта и фабрики, а не от конкретных реализаций. Это упрощает замену или добавление новых типов продуктов.
  • Соблюдение принципа открытости/закрытости (OCP): Можно вводить новые типы продуктов, не изменяя существующий клиентский код, который использует фабрику.

Пример (Простая Фабрика на Python):

from abc import ABC, abstractmethod

# Абстрактный продукт
class PaymentMethod(ABC):
    @abstractmethod
    def pay(self, amount: float):
        pass

# Конкретные продукты
class CreditCard(PaymentMethod):
    def pay(self, amount: float):
        print(f"Оплачено {amount} кредитной картой.")

class PayPal(PaymentMethod):
    def pay(self, amount: float):
        print(f"Оплачено {amount} через PayPal.")

# Фабрика для создания объектов
class PaymentFactory:
    @staticmethod
    def get_payment_method(method: str) -> PaymentMethod:
        if method == "credit_card":
            return CreditCard()
        elif method == "paypal":
            return PayPal()
        raise ValueError(f"Неизвестный метод оплаты: {method}")

# Клиентский код
payment_method = PaymentFactory.get_payment_method("paypal")
payment_method.pay(100.50)
# Вывод: Оплачено 100.5 через PayPal.

Когда применять:

  • Когда заранее неизвестно, объекты каких именно классов нужно будет создавать.
  • Когда система должна быть независимой от процесса создания и композиции своих продуктов.
  • Когда вы хотите предоставить пользователям библиотеки только интерфейс для создания объектов, скрыв реализацию.