Ответ
Абстрактная фабрика — это порождающий паттерн проектирования, который предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов.
Ключевая идея: Паттерн инкапсулирует логику выбора конкретной реализации и позволяет клиенту работать с абстрактными типами, не зная, какая именно фабрика и какие продукты были созданы.
Когда использовать:
- Когда система должна быть независима от процесса создания, композиции и представления своих продуктов.
- Когда нужно работать с одним из нескольких семейств продуктов (например, GUI для разных ОС: Windows, macOS).
- Когда вы хотите предоставить библиотеку классов, раскрывая только их интерфейсы, но не реализацию.
Пример на Python: Создадим фабрики для производства мебели в разных стилях (модерн и викторианский). Каждая фабрика производит полный набор: стул и стол.
from abc import ABC, abstractmethod
# --- Абстрактные продукты ---
class AbstractChair(ABC):
@abstractmethod
def sit_on(self) -> str:
pass
class AbstractTable(ABC):
@abstractmethod
def put_on(self) -> str:
pass
# --- Конкретные продукты (стиль Модерн) ---
class ModernChair(AbstractChair):
def sit_on(self) -> str:
return "Сидим на современном стуле."
class ModernTable(AbstractTable):
def put_on(self) -> str:
return "Ставим на современный стол."
# --- Абстрактная фабрика ---
class AbstractFurnitureFactory(ABC):
@abstractmethod
def create_chair(self) -> AbstractChair:
pass
@abstractmethod
def create_table(self) -> AbstractTable:
pass
# --- Конкретная фабрика (Модерн) ---
class ModernFurnitureFactory(AbstractFurnitureFactory):
def create_chair(self) -> AbstractChair:
return ModernChair()
def create_table(self) -> AbstractTable:
return ModernTable()
# --- Клиентский код ---
def client_code(factory: AbstractFurnitureFactory):
chair = factory.create_chair()
table = factory.create_table()
print(chair.sit_on())
print(table.put_on())
# Используем фабрику для создания мебели в стиле Модерн
print("Клиент: Заказываю мебель в стиле Модерн.")
client_code(ModernFurnitureFactory())
Клиентский код зависит только от абстрактных классов AbstractFurnitureFactory
, AbstractChair
, AbstractTable
, что позволяет легко подменить фабрику (например, на VictorianFurnitureFactory
) без изменения самого клиента.