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 тестване, feature flags). За статични зависимости Hilt напълно автоматизира създаването на обекти — разработчикът пише само интерфейса и анотациите.

Често задавани въпроси

Как се различава Factory Method от Abstract Factory?

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

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

Factory е оправдана за динамичен избор на имплементация по време на изпълнение (A/B тестове, feature flags, различно 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 приема параметри (repository, application context) и ги предава на конструктора на ViewModel. Hilt генерира Factory автоматично за @HiltViewModel.

Как Factory се свързва с принципа на отвореност/затвореност?

Factory реализира принципа Open-Closed: системата е отворена за разширение (нова имплементация се добавя във фабриката), но затворена за модификация (клиентският код не се променя). Добавянето на нов тип продукт изисква промяна само във фабриката, а не във всички клиенти. Това е ключовото предимство на Factory пред директното създаване на обекти.

Резюме

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

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

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също