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

Что такое Абстрактная фабрика?

1.2 Junior🔥 121 комментариев
#Архитектура и паттерны

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое паттерн «Абстрактная фабрика»?

Абстрактная фабрика (Abstract Factory) — это один из классических паттернов проектирования, относящийся к категории порождающих паттернов (creational patterns). Его основная цель — предоставить интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов без указания их конкретных классов. Этот паттерн особенно полезен в iOS разработке, когда система должна быть независимой от способа создания, композиции и представления своих продуктов, а также когда необходимо поддерживать несколько семейств объектов (например, разные UI стили, версии для различных платформ или тематические наборы компонентов).

Ключевые компоненты паттерна

  1. AbstractFactory (Абстрактная фабрика) — интерфейс или абстрактный класс, объявляющий методы для создания каждого из продуктов семейства (например, createButton(), createTextField()).
  2. ConcreteFactory (Конкретная фабрика) — реализация абстрактной фабрики. Каждая конкретная фабрика отвечает за создание продуктов одного определенного семейства (например, LightThemeFactory создает светлые кнопки и поля, DarkThemeFactory — темные).
  3. AbstractProduct (Абстрактный продукт) — интерфейс для типа продукта (например, протокол Button).
  4. ConcreteProduct (Конкретный продукт) — конкретный объект, создаваемый фабрикой. Он реализует интерфейс абстрактного продукта (например, класс LightButton, реализующий протокол Button).
  5. Client (Клиент) — код, который использует фабрику для создания продуктов. Он работает только с абстрактными типами (фабрикой и продуктами), что обеспечивает гибкость и заменяемость.

Пример реализации в Swift

Рассмотрим ситуацию, где необходимо создавать UI элементы для двух разных тем оформления: светлой (Light) и темной (Dark).

// Абстрактные продукты (Протоколы)
protocol Button {
    func render()
    func onTap()
}

protocol TextField {
    func render()
    func onFocus()
}

// Абстрактная фабрика (Протокол)
protocol ThemeFactory {
    func createButton() -> Button
    func createTextField() -> TextField
}

// Конкретные продукты для светлой темы
class LightButton: Button {
    func render() {
        print("Отрисовка светлой кнопки с белым фоном")
    }
    func onTap() {
        print("Светлая кнопка: действие выполнено")
    }
}

class LightTextField: TextField {
    func render() {
        print("Отрисовка светлого текстового поля с серой рамкой")
    }
    func onFocus() {
        print("Светлое поле: получен фокус")
    }
}

// Конкретная фабрика для светлой темы
class LightThemeFactory: ThemeFactory {
    func createButton() -> Button {
        return LightButton()
    }
    func createTextField() -> TextField {
        return LightTextField()
    }
}

// Конкретные продукты для темной темы
class DarkButton: Button {
    func render() {
        print("Отрисовка темной кнопки с черным фоном")
    }
    func onTap() {
        print("Темная кнопка: действие выполнено")
    }
}

class DarkTextField: TextField {
    func render() {
        print("Отрисовка темного текстового поля с синей рамкой")
    }
    func onFocus() {
        print("Темное поле: получен фокус")
    }
}

// Конкретная фабрика для темной темы
class DarkThemeFactory: ThemeFactory {
    func createButton() -> Button {
        return DarkButton()
    }
    func createTextField() -> TextField {
        return DarkTextField()
    }
}

// Клиентский код
class UIViewController {
    private let factory: ThemeFactory

    init(factory: ThemeFactory) {
        self.factory = factory
    }

    func buildUI() {
        let button = factory.createButton()
        let textField = factory.createTextField()

        button.render()
        textField.render()
    }
}

// Использование
let lightThemeController = UIViewController(factory: LightThemeFactory())
lightThemeController.buildUI()
// Вывод:
// Отрисовка светлой кнопки с белым фоном
// Отрисовка светлого текстового поля с серой рамкой

let darkThemeController = UIViewController(factory: DarkThemeFactory())
darkThemeController.buildUI()
// Вывод:
// Отрисовка темной кнопки с черным фоном
// Отрисовка темного текстового поля с синей рамкой

Преимущества использования в iOS разработке

  • Соблюдение принципа инверсии зависимостей (Dependency Inversion Principle): Клиентский код зависит от абстракций (ThemeFactory, Button, TextField), а не от конкретных реализаций.
  • Упрощение поддержки нескольких вариантов или семейств: Добавление новой темы (например, HighContrastTheme) требует лишь создания новой конкретной фабрики и новых классов продуктов, без изменения существующего клиентского кода.
  • Гарантия совместимости продуктов: Фабрика создает целое семейство объектов, которые заведомо совместимы друг с другом (например, все элементы темной темы используют одну цветовую палитру).
  • Сокрытие сложности создания объектов: Клиент не знает, как именно создаются и конфигурируются конкретные продукты (например, кнопка может иметь сложную иерархию view или специфические анимации).

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

  • Система должна конфигурироваться одним из нескольких семейств взаимосвязанных продуктов.
  • Вы хотите предоставить библиотеку продуктов, скрывая детали их реализации и обеспечивая только их интерфейсы.
  • В приложении есть несколько стилей, тем или платформно-специфичных наборов компонентов (например, отдельные наборы UI для iOS и Apple Watch).

В iOS экосистеме подход, аналогичный абстрактной фабрике, можно наблюдать в использовании различных стратегий оформления (Theme) или в архитектуре, где сервис-локатор (Service Locator) или фабрика зависимостей (Dependency Factory) создает связанные сервисы для конкретного модуля или контекста. Это делает код более гибким, тестируемым и готовым к масштабированию.

Что такое Абстрактная фабрика? | PrepBro