← Назад к вопросам

За счет чего Абстрактная Фабрика понимает, с какой реализацией работать?

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', фабрика создаст соответствующий набор компонентов. Главная идея — разделить логику выбора реализации от её использования."