Factory: суть паттерна Factory Method и Abstract Factory

Автор: IT Sectr Опубликовано: 2026-02-17 Время чтения: 7 мин

Factory — порождающий паттерн, делегирующий создание объектов фабричным методам. В мобильной разработке Factory Method и Abstract Factory используются для создания ViewModel, NetworkClient, Repository и других зависимостей. Factory изолирует логику инстанцирования, упрощая замену реализаций. Подробнее — в Refactoring Guru: Factory Method.

Главное

  • Factory — порождающий паттерн для создания объектов без указания конкретного класса
  • Factory Method — метод в суперклассе, переопределяемый в подклассах для создания объектов
  • Abstract Factory — интерфейс для создания семейств взаимосвязанных объектов
  • Тестирование — фабрики упрощают замену реализаций на mock-объекты в тестах
  • DI vs Factory — Dependency Injection заменяет фабрики в современных приложениях

Что такое Factory: суть паттерна создания объектов?

Factory — порождающий паттерн проектирования из каталога GoF. Основная идея: вынести логику создания объектов из клиентского кода в отдельный метод или класс. Клиент работает с интерфейсом или абстрактным классом, а конкретная реализация создаётся фабрикой. Это реализует принцип инверсии зависимостей (Dependency Inversion): клиент не зависит от конкретных классов, только от абстракций.

Две разновидности Factory: Factory Method и Abstract Factory. Factory Method — один метод в классе, который подклассы переопределяют для создания объектов. Abstract Factory — интерфейс с семейством фабричных методов для создания групп взаимосвязанных объектов. Оба варианта решают одну задачу: клиент не вызывает new MyClass() напрямую, а просит фабрику создать объект по его типу или параметрам.

Factory vs new() — прямое создание объектов жёстко связывает код с конкретной реализацией. Factory добавляет прослойку: изменение реализации требует правки только в фабрике, а не во всех клиентах. В мобильной разработке Factory активно используется для создания ViewModel (ViewModelProvider.Factory), сетевых клиентов (Retrofit.create()), адаптеров списков и фабрик сериализации. DI-контейнеры (Dagger, Koin) автоматически генерируют фабрики.

Factory Method: Swift и Kotlin примеры

Factory Method — метод, объявленный в протоколе или абстрактном классе, который возвращает объект определённого типа. Подклассы реализуют метод, создавая конкретные экземпляры. В Swift это может быть static method в протоколе или метод в базовом классе. В Kotlin — companion object с фабричным методом или open fun в абстрактном классе. Паттерн широко применяется для создания парсеров, фабрик ошибок и строителей запросов.

swift
protocol PaymentGateway {
    func processPayment(amount: Decimal) async throws -> PaymentResult
}

final class StripeGateway: PaymentGateway { /* ... */ }
final class ApplePayGateway: PaymentGateway { /* ... */ }

enum PaymentType { case stripe, applePay }

final class PaymentFactory {
    // Factory Method
    static func create(type: PaymentType) -> PaymentGateway {
        switch type {
        case .stripe: return StripeGateway()
        case .applePay: return ApplePayGateway()
        }
    }
}

// Использование
let gateway = PaymentFactory.create(type: .stripe)

Kotlin-версия Factory Method использует companion object или sealed class для ограничения типов. Sealed class гарантирует, что ветка when покрывает все возможные типы — компилятор проверяет полноту. Это типично для Android-проектов, где фабрика создаёт разные реализации Repository или DataSource в зависимости от build flavour или конфигурации.

kotlin
sealed class PaymentType {
    object Stripe : PaymentType()
    object ApplePay : PaymentType()
}

interface PaymentGateway {
    suspend fun processPayment(amount: BigDecimal): PaymentResult
}

class PaymentFactory {
    companion object {
        fun create(type: PaymentType): PaymentGateway = when (type) {
            PaymentType.Stripe -> StripeGateway()
            PaymentType.ApplePay -> ApplePayGateway()
        }
    }
}

Abstract Factory: семейства взаимосвязанных объектов

Abstract Factory — паттерн для создания семейств взаимосвязанных или взаимозависимых объектов без указания их конкретных классов. Клиент работает с интерфейсом абстрактной фабрики, который определяет методы для создания каждого продукта семейства. Конкретная фабрика реализует интерфейс и создаёт объекты определённого варианта. Например, фабрика UI-компонентов для iOS создаёт UIButton, UILabel, UITableView, а для Android — Button, TextView, RecyclerView.

Abstract Factory vs Factory Method — Factory Method создаёт один тип объекта через наследование, Abstract Factory создаёт семейство объектов через композицию. Factory Method переопределяется в подклассах, Abstract Factory предоставляет несколько фабричных методов через протокол. Abstract Factory часто содержит несколько Factory Method. В мобильной разработке Abstract Factory используется для платформозависимых компонентов, тем оформления и фабрик баз данных.

ХарактеристикаFactory MethodAbstract Factory
Количество продуктовОдинСемейство (несколько)
МеханизмНаследование (override)Композиция (protocol/interface)
Пример iOSPaymentFactory.create()UIComponentFactory для iOS/Android
Пример AndroidViewModelProvider.FactoryThemeFactory: создание кнопок, текстов, карточек
ГибкостьПростая замена подклассаПолная замена семейства

Реальный кейс Abstract Factory в Android — реализация разных типов баз данных (SQLite vs Room) через единый интерфейс DatabaseFactory. Фабрика создаёт DAO-объекты, миграции и пулы соединений. В iOS — фабрика сервисов для разных сред (Development/Staging/Production). Abstract Factory редко используется напрямую — её функции берут на себя DI-контейнеры (Dagger Module, Swinject Assembly).

Factory в iOS: протоколы и статические методы

Swift Factory реализуется через протоколы и статические методы. Протокол Factory объявляет метод create(), возвращающий абстрактный тип. Конкретная фабрика реализует протокол и создаёт нужные объекты. Swift не требует отдельного класса-фабрики для простых случаев — достаточно статического метода в enum или struct. Для сложных сценариев используется Factory-протокол с внедрением через DI.

Factory в iOS SDK — множество системных фабрик: UIStoryboard.instantiateViewController(withIdentifier:), NSKeyedUnarchiver.unarchivedObject(ofClass:from:), JSONDecoder().decode(_:from:). Разработчики создают фабрики для ViewController (StoryboardFactory), для сервисов (ServiceFactory) и для моделей данных. Factory Method активно используется в архитектурах VIPER и Clean Swift для создания модулей экранов.

Factory + DI — современная альтернатива: DI-контейнер (Swinject, Factory) автоматически генерирует фабрики для зарегистрированных типов. Контейнер хранит рецепты создания объектов и разрешает зависимости. Factory-библиотека (github.com/hmlongco/Factory) использует @Injected(.service) для автоматического внедрения. DI-фабрики тестируются заменой целого модуля одной строкой: container.register { MockService() }.

Factory в Android: companion factory и DI-модули

Android Factory — классический пример: ViewModelProvider.Factory для создания ViewModel с параметрами. Google рекомендует использовать Hilt для автоматической генерации фабрик ViewModel — аннотация @HiltViewModel создаёт Factory автоматически. Для простых объектов используется companion object с методом create() или invoke(). В Kotlin оператор invoke позволяет вызывать фабрику как функцию: Factory(param).

Factory в Jetpack Compose — фабрики используются для создания состояний и эффектов. remember { Factory.create() } создаёт объект при первом рендеринге и сохраняет его на время жизни composable. ViewModel в Compose создаётся через viewModel() — это фабрика, управляемая Hilt. В Compose фабрики реже встречаются явно, так как DI и Compose StateManager берут на себя создание объектов.

Factory vs Hilt — Dagger/Hilt автоматически генерирует фабрики на этапе компиляции. @Module + @Provides заменяет Factory Method, @Binds заменяет Abstract Factory. Ручные фабрики остаются актуальными для динамического выбора реализации в рантайме (A/B тестирование, фича-флаги). Для статических зависимостей Hilt полностью автоматизирует создание объектов — разработчик пишет только интерфейс и аннотации.

Часто задаваемые вопросы

Чем Factory Method отличается от Abstract Factory?

Factory Method создаёт один тип объекта через наследование — подкласс переопределяет фабричный метод. Abstract Factory создаёт семейство объектов через композицию — интерфейс фабрики объявляет методы для нескольких продуктов. Factory Method проще, Abstract Factory гибче для платформозависимых или тематических компонентов.

Когда использовать Factory вместо DI?

Factory оправдана для динамического выбора реализации в рантайме (A/B тесты, фича-флаги, разный API для разных тарифов). DI (Hilt, Dagger, Koin) предпочтительнее для статических зависимостей — он автоматизирует создание и внедрение. Factory и DI не исключают друг друга: DI может использовать Factory внутри модуля.

Как тестировать код, использующий Factory?

Factory тестируется подменой фабрики через протокол. В тесте создаётся TestFactory, реализующая тот же протокол и возвращающая mock-объекты. Для статических Factory-методов тестирование сложнее — потребуется DI-контейнер или swizzling. Рекомендуется всегда использовать протокол для Factory, чтобы сохранить тестируемость.

Что такое ViewModelProvider.Factory в Android?

ViewModelProvider.Factory — интерфейс из Jetpack, позволяющий создавать ViewModel с кастомными параметрами. Без фабрики ViewModel создаётся через рефлексию и может иметь только пустой конструктор. Factory принимает параметры (репозиторий, application context) и передаёт их в конструктор ViewModel. Hilt генерирует Factory автоматически для @HiltViewModel.

Как Factory связан с принципом открытости/закрытости?

Factory реализует Open-Closed Principle: система открыта для расширения (новая реализация добавляется в фабрику), но закрыта для модификации (клиентский код не меняется). Добавление нового типа продукта требует правки только в фабрике, а не во всех клиентах. Это ключевое преимущество Factory перед прямым созданием объектов.

Итоги

  • Factory — порождающий паттерн для создания объектов через абстракцию
  • Factory Method — один метод, переопределяемый в подклассах
  • Abstract Factory — интерфейс для создания семейства объектов
  • iOS — протоколы и статические методы для фабрик
  • Android — companion object, ViewModelProvider.Factory, Hilt
  • DI vs Factory — DI автоматизирует создание, Factory для динамического выбора
  • Тестирование — протокол Factory обязателен для подмены реализаций

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также