← Назад к вопросам
За счет чего Абстрактная Фабрика понимает, с какой реализацией работать?
2.2 Middle🔥 61 комментариев
#Архитектура и паттерны
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Абстрактная Фабрика — Выбор реализации
Абстрактная Фабрика — это паттерн, который решает проблему создания семейств связанных объектов. Фабрика понимает, с какой реализацией работать благодаря информации, переданной извне.
Способ 1: Параметр в конструктор
from abc import ABC, abstractmethod
class Button(ABC):
@abstractmethod
def click(self):
pass
class WindowsButton(Button):
def click(self):
return 'Windows button'
class MacButton(Button):
def click(self):
return 'Mac button'
class GUIFactory(ABC):
@abstractmethod
def create_button(self) -> Button:
pass
class WindowsFactory(GUIFactory):
def create_button(self) -> Button:
return WindowsButton()
class MacFactory(GUIFactory):
def create_button(self) -> Button:
return MacButton()
# Выбор фабрики извне
os_type = 'windows'
factory = WindowsFactory() if os_type == 'windows' else MacFactory()
button = factory.create_button()
print(button.click())
Способ 2: Регистрация через словарь
class FactorySelector:
_factories = {
'windows': WindowsFactory,
'mac': MacFactory,
}
@classmethod
def get_factory(cls, os_name: str) -> GUIFactory:
factory_class = cls._factories.get(os_name)
if not factory_class:
raise ValueError(f'Unknown OS: {os_name}')
return factory_class()
# Использование
import platform
os_name = platform.system().lower()
factory = FactorySelector.get_factory(os_name)
Способ 3: Переменные окружения
import os
class ConfigFactory:
@classmethod
def create(cls) -> GUIFactory:
os_type = os.getenv('UI_OS', 'windows')
factories = {
'windows': WindowsFactory,
'mac': MacFactory,
}
return factories[os_type]()
factory = ConfigFactory.create()
Способ 4: Динамическая регистрация
class PluginFactory:
_registry = {}
@classmethod
def register(cls, name, factory_class):
cls._registry[name] = factory_class
@classmethod
def get(cls, name):
return cls._registry[name]()
PluginFactory.register('windows', WindowsFactory)
PluginFactory.register('mac', MacFactory)
factory = PluginFactory.get('windows')
Реальный пример: БД
class DatabaseConnection(ABC):
@abstractmethod
def connect(self):
pass
class PostgresConnection(DatabaseConnection):
def connect(self):
return 'PostgreSQL connected'
class MySQLConnection(DatabaseConnection):
def connect(self):
return 'MySQL connected'
class DBFactory(ABC):
@abstractmethod
def create_connection(self) -> DatabaseConnection:
pass
class PostgresFactory(DBFactory):
def create_connection(self):
return PostgresConnection()
class MySQLFactory(DBFactory):
def create_connection(self):
return MySQLConnection()
# Выбор из конфига
import configparser
config = configparser.ConfigParser()
config.read('config.ini')
db_type = config.get('database', 'type')
factories = {
'postgres': PostgresFactory,
'mysql': MySQLFactory,
}
factory = factories[db_type]()
connection = factory.create_connection()
print(connection.connect())
Ключевой момент
Фабрика НЕ сама решает реализацию. Это решение приходит извне:
- Параметр функции
- Конфигурация
- Переменные окружения
- Регистрация в runtime
Это позволяет менять реализацию без изменения основного кода.
На интервью
Ответи: "Абстрактная Фабрика получает информацию о нужной реализации извне — через параметры, конфигурацию или регистрацию. Например, если передать 'windows' или 'mac', фабрика создаст соответствующий набор компонентов. Главная идея — разделить логику выбора реализации от её использования."