Чем отличается паттерн ‘Фабричный метод’ от ‘Абстрактной фабрики’

Ответ

Ключевое различие заключается в их цели и масштабе: Фабричный метод создает один объект, а Абстрактная фабрика — семейство взаимосвязанных объектов.

Фабричный метод (Factory Method)

Это порождающий паттерн, который определяет интерфейс для создания одного объекта, но позволяет подклассам изменять тип создаваемого объекта.

  • Цель: Делегировать создание экземпляров подклассам.
  • Аналогия: Специализированный цех, который производит один тип продукта (например, только кнопки).

Пример: Создание разных типов логгеров.

class Logger:
    def log(self, message): pass

class FileLogger(Logger): ...
class ConsoleLogger(Logger): ...

# Фабричный метод в создателе
class LoggerFactory:
    def create_logger(self) -> Logger:
        # Логика выбора логгера
        return FileLogger()

Абстрактная фабрика (Abstract Factory)

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

  • Цель: Гарантировать, что создаваемые объекты из разных семейств совместимы друг с другом.
  • Аналогия: Целый завод, который производит полный набор совместимых продуктов (например, UI-элементы для Windows: WinButton, WinCheckbox).

Пример: Создание UI-элементов для разных ОС.

class GUIFactory:
    def create_button(self): pass
    def create_checkbox(self): pass

class WindowsFactory(GUIFactory):
    def create_button(self): return WinButton()
    def create_checkbox(self): return WinCheckbox()

class MacFactory(GUIFactory):
    def create_button(self): return MacButton()
    def create_checkbox(self): return MacCheckbox()

Итог:

Критерий Фабричный метод Абстрактная фабрика
Продукт Один объект Семейство объектов
Реализация Через наследование (один метод) Через композицию (объект-фабрика)
Иерархия Одна иерархия продуктов Несколько иерархий продуктов

Ответ 18+ 🔞

Давай разберём эту дичь, а то голова уже пухнет от этих фабрик. Представь, что ты заходишь в заведение, а там тебе предлагают: «Хочешь один бутерброд или сразу весь комплект — с кофе, салатом и пончиком?». Вот примерно так и тут.

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

class Табуреткодел:
    def сделай_мебель(self):
        return Табуретка()  # Вот он, ебаный, один продукт!

class Стулодел(Табуреткодел):
    def сделай_мебель(self):
        return Стул()  # А тут уже стул, ёпта!

Абстрактная фабрика — это уже не дядя Вася, а целый заводской комплекс, блядь. Ты приходишь и говоришь: «Мне нужен полный набор мебели в стиле „Лохматый прованс“». И тебе выдают: стул в этом стиле, стол, шкаф — всё, чтобы друг с другом не поругалось. Если завтра захочешь «Хай-тек» — идёшь на другой завод, и там тебе наштампуют всю семейку в другом дизайне, но тоже совместимую.

class МебельнаяФабрика:
    def сделай_стул(self): pass
    def сделай_стол(self): pass  # Целое семейство, ёбушки-воробушки!

class ПровансФабрика(МебельнаяФабрика):
    def сделай_стул(self): return СтулВЦветочек()
    def сделай_стол(self): return СтолСКозьейНогой()

class ХайТекФабрика(МебельнаяФабрика):
    def сделай_стул(self): return СтулИзХромированнойПизды()
    def сделай_стол(self): return СтолСПодсветкой()

Короче, резюмирую, чтобы в голове не еблось:

  • Фабричный метод — ты получаешь один хуй. Один объект. Решает, какой именно, подкласс.
  • Абстрактная фабрика — ты получаешь целую охапку связанного хуя. Несколько объектов, которые друг с другом дружат. Решает, какое именно семейство, конкретная фабрика.

Если запутался — представь: фабричный метод это как заказать пиццу (одну, но разную). А абстрактная фабрика — это как заказать комплексный обед (первое, второе, компот — всё в одном стиле, чтоб не выебывалось). Вот и вся магия, блядь.